xai-review 0.27.0__tar.gz → 0.28.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 (374) hide show
  1. {xai_review-0.27.0 → xai_review-0.28.0}/PKG-INFO +8 -5
  2. {xai_review-0.27.0 → xai_review-0.28.0}/README.md +7 -4
  3. xai_review-0.28.0/ai_review/cli/commands/run_inline_reply_review.py +7 -0
  4. xai_review-0.28.0/ai_review/cli/commands/run_summary_reply_review.py +7 -0
  5. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/main.py +17 -0
  6. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/schema/comments.py +14 -0
  7. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/schema/pull_request.py +1 -5
  8. xai_review-0.28.0/ai_review/clients/bitbucket/pr/schema/user.py +7 -0
  9. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/client.py +35 -4
  10. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/schema/comments.py +21 -0
  11. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/schema/pull_request.py +1 -4
  12. xai_review-0.28.0/ai_review/clients/github/pr/schema/user.py +6 -0
  13. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/types.py +11 -1
  14. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/client.py +32 -1
  15. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/schema/changes.py +1 -5
  16. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/schema/discussions.py +17 -7
  17. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/schema/notes.py +3 -0
  18. xai_review-0.28.0/ai_review/clients/gitlab/mr/schema/user.py +7 -0
  19. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/types.py +16 -7
  20. xai_review-0.28.0/ai_review/libs/config/prompt.py +155 -0
  21. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/review.py +2 -0
  22. xai_review-0.28.0/ai_review/libs/llm/output_json_parser.py +60 -0
  23. xai_review-0.28.0/ai_review/prompts/default_inline_reply.md +10 -0
  24. xai_review-0.28.0/ai_review/prompts/default_summary_reply.md +14 -0
  25. xai_review-0.28.0/ai_review/prompts/default_system_inline_reply.md +31 -0
  26. xai_review-0.28.0/ai_review/prompts/default_system_summary_reply.md +13 -0
  27. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/artifacts/schema.py +2 -2
  28. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/hook/constants.py +14 -0
  29. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/hook/service.py +95 -4
  30. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/hook/types.py +18 -2
  31. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/prompt/adapter.py +1 -1
  32. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/prompt/service.py +49 -3
  33. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/prompt/tools.py +21 -0
  34. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/prompt/types.py +23 -0
  35. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/review/gateway/comment.py +45 -6
  36. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/review/gateway/llm.py +2 -1
  37. xai_review-0.28.0/ai_review/services/review/gateway/types.py +50 -0
  38. xai_review-0.28.0/ai_review/services/review/internal/inline/service.py +40 -0
  39. xai_review-0.28.0/ai_review/services/review/internal/inline/types.py +8 -0
  40. xai_review-0.28.0/ai_review/services/review/internal/inline_reply/schema.py +23 -0
  41. xai_review-0.28.0/ai_review/services/review/internal/inline_reply/service.py +20 -0
  42. xai_review-0.28.0/ai_review/services/review/internal/inline_reply/types.py +8 -0
  43. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/review/internal}/policy/service.py +2 -1
  44. xai_review-0.28.0/ai_review/services/review/internal/policy/types.py +15 -0
  45. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/review/internal}/summary/service.py +2 -2
  46. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/review/internal}/summary/types.py +1 -1
  47. xai_review-0.28.0/ai_review/services/review/internal/summary_reply/schema.py +8 -0
  48. xai_review-0.28.0/ai_review/services/review/internal/summary_reply/service.py +15 -0
  49. xai_review-0.28.0/ai_review/services/review/internal/summary_reply/types.py +8 -0
  50. xai_review-0.28.0/ai_review/services/review/runner/context.py +72 -0
  51. xai_review-0.28.0/ai_review/services/review/runner/inline.py +80 -0
  52. xai_review-0.28.0/ai_review/services/review/runner/inline_reply.py +80 -0
  53. xai_review-0.28.0/ai_review/services/review/runner/summary.py +71 -0
  54. xai_review-0.28.0/ai_review/services/review/runner/summary_reply.py +79 -0
  55. xai_review-0.28.0/ai_review/services/review/runner/types.py +6 -0
  56. xai_review-0.28.0/ai_review/services/review/service.py +127 -0
  57. xai_review-0.28.0/ai_review/services/vcs/bitbucket/adapter.py +24 -0
  58. xai_review-0.28.0/ai_review/services/vcs/bitbucket/client.py +250 -0
  59. xai_review-0.28.0/ai_review/services/vcs/github/adapter.py +35 -0
  60. xai_review-0.28.0/ai_review/services/vcs/github/client.py +232 -0
  61. xai_review-0.28.0/ai_review/services/vcs/gitlab/adapter.py +26 -0
  62. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/vcs/gitlab/client.py +91 -38
  63. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/vcs/types.py +34 -0
  64. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/bitbucket.py +2 -2
  65. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/github.py +35 -6
  66. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/gitlab.py +42 -3
  67. xai_review-0.28.0/ai_review/tests/fixtures/libs/llm/output_json_parser.py +13 -0
  68. xai_review-0.28.0/ai_review/tests/fixtures/services/hook.py +8 -0
  69. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/llm.py +8 -5
  70. xai_review-0.28.0/ai_review/tests/fixtures/services/prompt.py +113 -0
  71. xai_review-0.28.0/ai_review/tests/fixtures/services/review/base.py +41 -0
  72. xai_review-0.28.0/ai_review/tests/fixtures/services/review/gateway/comment.py +98 -0
  73. xai_review-0.28.0/ai_review/tests/fixtures/services/review/gateway/llm.py +17 -0
  74. {xai_review-0.27.0/ai_review/tests/fixtures/services/review → xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal}/inline.py +8 -6
  75. xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal/inline_reply.py +25 -0
  76. xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal/policy.py +28 -0
  77. xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal/summary.py +21 -0
  78. xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal/summary_reply.py +19 -0
  79. xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner/context.py +50 -0
  80. xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner/inline.py +50 -0
  81. xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner/inline_reply.py +50 -0
  82. xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner/summary.py +50 -0
  83. xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner/summary_reply.py +50 -0
  84. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/vcs.py +23 -0
  85. xai_review-0.28.0/ai_review/tests/suites/cli/test_main.py +54 -0
  86. xai_review-0.28.0/ai_review/tests/suites/libs/config/test_prompt.py +137 -0
  87. xai_review-0.28.0/ai_review/tests/suites/libs/llm/test_output_json_parser.py +155 -0
  88. xai_review-0.28.0/ai_review/tests/suites/services/hook/test_service.py +177 -0
  89. xai_review-0.28.0/ai_review/tests/suites/services/llm/gemini/__init__.py +0 -0
  90. xai_review-0.28.0/ai_review/tests/suites/services/llm/ollama/__init__.py +0 -0
  91. xai_review-0.28.0/ai_review/tests/suites/services/llm/openai/__init__.py +0 -0
  92. xai_review-0.28.0/ai_review/tests/suites/services/prompt/__init__.py +0 -0
  93. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/prompt/test_adapter.py +3 -3
  94. xai_review-0.28.0/ai_review/tests/suites/services/prompt/test_service.py +215 -0
  95. xai_review-0.28.0/ai_review/tests/suites/services/prompt/test_tools.py +157 -0
  96. xai_review-0.28.0/ai_review/tests/suites/services/review/__init__.py +0 -0
  97. xai_review-0.28.0/ai_review/tests/suites/services/review/gateway/__init__.py +0 -0
  98. xai_review-0.28.0/ai_review/tests/suites/services/review/gateway/test_comment.py +253 -0
  99. xai_review-0.28.0/ai_review/tests/suites/services/review/gateway/test_llm.py +82 -0
  100. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/__init__.py +0 -0
  101. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/inline/__init__.py +0 -0
  102. {xai_review-0.27.0/ai_review/tests/suites/services/review → xai_review-0.28.0/ai_review/tests/suites/services/review/internal}/inline/test_schema.py +1 -1
  103. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/inline/test_service.py +81 -0
  104. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/inline_reply/__init__.py +0 -0
  105. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py +57 -0
  106. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/inline_reply/test_service.py +72 -0
  107. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/policy/__init__.py +0 -0
  108. {xai_review-0.27.0/ai_review/tests/suites/services/review → xai_review-0.28.0/ai_review/tests/suites/services/review/internal}/policy/test_service.py +1 -1
  109. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/summary/__init__.py +0 -0
  110. {xai_review-0.27.0/ai_review/tests/suites/services/review → xai_review-0.28.0/ai_review/tests/suites/services/review/internal}/summary/test_schema.py +1 -1
  111. {xai_review-0.27.0/ai_review/tests/suites/services/review → xai_review-0.28.0/ai_review/tests/suites/services/review/internal}/summary/test_service.py +2 -2
  112. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/summary_reply/__init__.py +0 -0
  113. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py +19 -0
  114. xai_review-0.28.0/ai_review/tests/suites/services/review/internal/summary_reply/test_service.py +21 -0
  115. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/__init__.py +0 -0
  116. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/test_context.py +89 -0
  117. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/test_inline.py +100 -0
  118. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/test_inline_reply.py +109 -0
  119. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/test_summary.py +87 -0
  120. xai_review-0.28.0/ai_review/tests/suites/services/review/runner/test_summary_reply.py +97 -0
  121. xai_review-0.28.0/ai_review/tests/suites/services/review/test_service.py +93 -0
  122. xai_review-0.28.0/ai_review/tests/suites/services/vcs/__init__.py +0 -0
  123. xai_review-0.28.0/ai_review/tests/suites/services/vcs/bitbucket/__init__.py +0 -0
  124. xai_review-0.28.0/ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py +109 -0
  125. xai_review-0.27.0/ai_review/tests/suites/services/vcs/bitbucket/test_service.py → xai_review-0.28.0/ai_review/tests/suites/services/vcs/bitbucket/test_client.py +88 -1
  126. xai_review-0.28.0/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
  127. xai_review-0.28.0/ai_review/tests/suites/services/vcs/github/test_adapter.py +162 -0
  128. xai_review-0.27.0/ai_review/tests/suites/services/vcs/github/test_service.py → xai_review-0.28.0/ai_review/tests/suites/services/vcs/github/test_client.py +102 -2
  129. xai_review-0.28.0/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
  130. xai_review-0.28.0/ai_review/tests/suites/services/vcs/gitlab/test_adapter.py +105 -0
  131. xai_review-0.27.0/ai_review/tests/suites/services/vcs/gitlab/test_service.py → xai_review-0.28.0/ai_review/tests/suites/services/vcs/gitlab/test_client.py +99 -1
  132. {xai_review-0.27.0 → xai_review-0.28.0}/pyproject.toml +1 -1
  133. {xai_review-0.27.0 → xai_review-0.28.0}/xai_review.egg-info/PKG-INFO +8 -5
  134. {xai_review-0.27.0 → xai_review-0.28.0}/xai_review.egg-info/SOURCES.txt +96 -23
  135. xai_review-0.27.0/ai_review/libs/config/prompt.py +0 -123
  136. xai_review-0.27.0/ai_review/services/review/inline/service.py +0 -54
  137. xai_review-0.27.0/ai_review/services/review/inline/types.py +0 -11
  138. xai_review-0.27.0/ai_review/services/review/service.py +0 -159
  139. xai_review-0.27.0/ai_review/services/vcs/bitbucket/client.py +0 -185
  140. xai_review-0.27.0/ai_review/services/vcs/github/client.py +0 -171
  141. xai_review-0.27.0/ai_review/tests/fixtures/services/prompt.py +0 -43
  142. xai_review-0.27.0/ai_review/tests/fixtures/services/review/summary.py +0 -19
  143. xai_review-0.27.0/ai_review/tests/suites/libs/config/test_prompt.py +0 -57
  144. xai_review-0.27.0/ai_review/tests/suites/services/hook/test_service.py +0 -93
  145. xai_review-0.27.0/ai_review/tests/suites/services/prompt/test_service.py +0 -171
  146. xai_review-0.27.0/ai_review/tests/suites/services/prompt/test_tools.py +0 -72
  147. xai_review-0.27.0/ai_review/tests/suites/services/review/inline/test_service.py +0 -107
  148. xai_review-0.27.0/ai_review/tests/suites/services/review/test_service.py +0 -126
  149. {xai_review-0.27.0 → xai_review-0.28.0}/LICENSE +0 -0
  150. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/__init__.py +0 -0
  151. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/__init__.py +0 -0
  152. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/commands/__init__.py +0 -0
  153. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/commands/run_context_review.py +0 -0
  154. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/commands/run_inline_review.py +0 -0
  155. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/commands/run_review.py +0 -0
  156. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/cli/commands/run_summary_review.py +0 -0
  157. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/__init__.py +0 -0
  158. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/__init__.py +0 -0
  159. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/client.py +0 -0
  160. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/__init__.py +0 -0
  161. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/client.py +0 -0
  162. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/schema/__init__.py +0 -0
  163. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/schema/files.py +0 -0
  164. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/pr/types.py +0 -0
  165. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/bitbucket/tools.py +0 -0
  166. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/claude/__init__.py +0 -0
  167. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/claude/client.py +0 -0
  168. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/claude/schema.py +0 -0
  169. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/claude/types.py +0 -0
  170. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gemini/__init__.py +0 -0
  171. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gemini/client.py +0 -0
  172. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gemini/schema.py +0 -0
  173. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gemini/types.py +0 -0
  174. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/__init__.py +0 -0
  175. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/client.py +0 -0
  176. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/__init__.py +0 -0
  177. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/schema/__init__.py +0 -0
  178. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/schema/files.py +0 -0
  179. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/pr/schema/reviews.py +0 -0
  180. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/github/tools.py +0 -0
  181. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/__init__.py +0 -0
  182. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/client.py +0 -0
  183. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
  184. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
  185. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/gitlab/tools.py +0 -0
  186. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/ollama/__init__.py +0 -0
  187. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/ollama/client.py +0 -0
  188. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/ollama/schema.py +0 -0
  189. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/ollama/types.py +0 -0
  190. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/openai/__init__.py +0 -0
  191. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/openai/client.py +0 -0
  192. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/openai/schema.py +0 -0
  193. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/clients/openai/types.py +0 -0
  194. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/config.py +0 -0
  195. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/__init__.py +0 -0
  196. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/asynchronous/__init__.py +0 -0
  197. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/asynchronous/gather.py +0 -0
  198. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/__init__.py +0 -0
  199. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/artifacts.py +0 -0
  200. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/base.py +0 -0
  201. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/core.py +0 -0
  202. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/http.py +0 -0
  203. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/__init__.py +0 -0
  204. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/base.py +0 -0
  205. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/claude.py +0 -0
  206. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/gemini.py +0 -0
  207. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/meta.py +0 -0
  208. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/ollama.py +0 -0
  209. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/llm/openai.py +0 -0
  210. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/logger.py +0 -0
  211. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/__init__.py +0 -0
  212. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/base.py +0 -0
  213. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/bitbucket.py +0 -0
  214. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/github.py +0 -0
  215. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/gitlab.py +0 -0
  216. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/config/vcs/pagination.py +0 -0
  217. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/constants/__init__.py +0 -0
  218. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/constants/llm_provider.py +0 -0
  219. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/constants/vcs_provider.py +0 -0
  220. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/diff/__init__.py +0 -0
  221. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/diff/models.py +0 -0
  222. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/diff/parser.py +0 -0
  223. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/diff/tools.py +0 -0
  224. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/__init__.py +0 -0
  225. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/client.py +0 -0
  226. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/event_hooks/__init__.py +0 -0
  227. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/event_hooks/base.py +0 -0
  228. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
  229. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/handlers.py +0 -0
  230. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/paginate.py +0 -0
  231. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/transports/__init__.py +0 -0
  232. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/http/transports/retry.py +0 -0
  233. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/json.py +0 -0
  234. {xai_review-0.27.0/ai_review/libs/template → xai_review-0.28.0/ai_review/libs/llm}/__init__.py +0 -0
  235. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/logger.py +0 -0
  236. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/resources.py +0 -0
  237. {xai_review-0.27.0/ai_review/prompts → xai_review-0.28.0/ai_review/libs/template}/__init__.py +0 -0
  238. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/libs/template/render.py +0 -0
  239. {xai_review-0.27.0/ai_review/resources → xai_review-0.28.0/ai_review/prompts}/__init__.py +0 -0
  240. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_context.md +0 -0
  241. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_inline.md +0 -0
  242. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_summary.md +0 -0
  243. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_system_context.md +0 -0
  244. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_system_inline.md +0 -0
  245. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/prompts/default_system_summary.md +0 -0
  246. {xai_review-0.27.0/ai_review/services → xai_review-0.28.0/ai_review/resources}/__init__.py +0 -0
  247. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/resources/pricing.yaml +0 -0
  248. {xai_review-0.27.0/ai_review/services/artifacts → xai_review-0.28.0/ai_review/services}/__init__.py +0 -0
  249. {xai_review-0.27.0/ai_review/services/cost → xai_review-0.28.0/ai_review/services/artifacts}/__init__.py +0 -0
  250. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/artifacts/service.py +0 -0
  251. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/artifacts/tools.py +0 -0
  252. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/artifacts/types.py +0 -0
  253. {xai_review-0.27.0/ai_review/services/diff → xai_review-0.28.0/ai_review/services/cost}/__init__.py +0 -0
  254. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/cost/schema.py +0 -0
  255. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/cost/service.py +0 -0
  256. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/cost/types.py +0 -0
  257. {xai_review-0.27.0/ai_review/services/git → xai_review-0.28.0/ai_review/services/diff}/__init__.py +0 -0
  258. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/diff/renderers.py +0 -0
  259. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/diff/schema.py +0 -0
  260. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/diff/service.py +0 -0
  261. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/diff/tools.py +0 -0
  262. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/diff/types.py +0 -0
  263. {xai_review-0.27.0/ai_review/services/llm → xai_review-0.28.0/ai_review/services/git}/__init__.py +0 -0
  264. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/git/service.py +0 -0
  265. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/git/types.py +0 -0
  266. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/hook/__init__.py +0 -0
  267. {xai_review-0.27.0/ai_review/services/llm/claude → xai_review-0.28.0/ai_review/services/llm}/__init__.py +0 -0
  268. {xai_review-0.27.0/ai_review/services/llm/gemini → xai_review-0.28.0/ai_review/services/llm/claude}/__init__.py +0 -0
  269. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/claude/client.py +0 -0
  270. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/factory.py +0 -0
  271. {xai_review-0.27.0/ai_review/services/llm/ollama → xai_review-0.28.0/ai_review/services/llm/gemini}/__init__.py +0 -0
  272. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/gemini/client.py +0 -0
  273. {xai_review-0.27.0/ai_review/services/llm/openai → xai_review-0.28.0/ai_review/services/llm/ollama}/__init__.py +0 -0
  274. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/ollama/client.py +0 -0
  275. {xai_review-0.27.0/ai_review/services/prompt → xai_review-0.28.0/ai_review/services/llm/openai}/__init__.py +0 -0
  276. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/openai/client.py +0 -0
  277. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/llm/types.py +0 -0
  278. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/prompt}/__init__.py +0 -0
  279. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/prompt/schema.py +0 -0
  280. {xai_review-0.27.0/ai_review/services/review/gateway → xai_review-0.28.0/ai_review/services/review}/__init__.py +0 -0
  281. {xai_review-0.27.0/ai_review/services/review/inline → xai_review-0.28.0/ai_review/services/review/gateway}/__init__.py +0 -0
  282. {xai_review-0.27.0/ai_review/services/review/policy → xai_review-0.28.0/ai_review/services/review/internal}/__init__.py +0 -0
  283. {xai_review-0.27.0/ai_review/services/review/summary → xai_review-0.28.0/ai_review/services/review/internal/inline}/__init__.py +0 -0
  284. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/review/internal}/inline/schema.py +0 -0
  285. {xai_review-0.27.0/ai_review/services/vcs → xai_review-0.28.0/ai_review/services/review/internal/inline_reply}/__init__.py +0 -0
  286. {xai_review-0.27.0/ai_review/services/vcs/bitbucket → xai_review-0.28.0/ai_review/services/review/internal/policy}/__init__.py +0 -0
  287. {xai_review-0.27.0/ai_review/services/vcs/github → xai_review-0.28.0/ai_review/services/review/internal/summary}/__init__.py +0 -0
  288. {xai_review-0.27.0/ai_review/services/review → xai_review-0.28.0/ai_review/services/review/internal}/summary/schema.py +0 -0
  289. {xai_review-0.27.0/ai_review/services/vcs/gitlab → xai_review-0.28.0/ai_review/services/review/internal/summary_reply}/__init__.py +0 -0
  290. {xai_review-0.27.0/ai_review/tests → xai_review-0.28.0/ai_review/services/review/runner}/__init__.py +0 -0
  291. {xai_review-0.27.0/ai_review/tests/fixtures → xai_review-0.28.0/ai_review/services/vcs}/__init__.py +0 -0
  292. {xai_review-0.27.0/ai_review/tests/fixtures/clients → xai_review-0.28.0/ai_review/services/vcs/bitbucket}/__init__.py +0 -0
  293. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/services/vcs/factory.py +0 -0
  294. {xai_review-0.27.0/ai_review/tests/fixtures/services → xai_review-0.28.0/ai_review/services/vcs/github}/__init__.py +0 -0
  295. {xai_review-0.27.0/ai_review/tests/fixtures/services/review → xai_review-0.28.0/ai_review/services/vcs/gitlab}/__init__.py +0 -0
  296. {xai_review-0.27.0/ai_review/tests/suites → xai_review-0.28.0/ai_review/tests}/__init__.py +0 -0
  297. {xai_review-0.27.0/ai_review/tests/suites/clients → xai_review-0.28.0/ai_review/tests/fixtures}/__init__.py +0 -0
  298. {xai_review-0.27.0/ai_review/tests/suites/clients/bitbucket → xai_review-0.28.0/ai_review/tests/fixtures/clients}/__init__.py +0 -0
  299. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/claude.py +0 -0
  300. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/gemini.py +0 -0
  301. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/ollama.py +0 -0
  302. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/clients/openai.py +0 -0
  303. {xai_review-0.27.0/ai_review/tests/suites/clients/claude → xai_review-0.28.0/ai_review/tests/fixtures/libs}/__init__.py +0 -0
  304. {xai_review-0.27.0/ai_review/tests/suites/clients/gemini → xai_review-0.28.0/ai_review/tests/fixtures/libs/llm}/__init__.py +0 -0
  305. {xai_review-0.27.0/ai_review/tests/suites/clients/github → xai_review-0.28.0/ai_review/tests/fixtures/services}/__init__.py +0 -0
  306. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
  307. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/cost.py +0 -0
  308. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/diff.py +0 -0
  309. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/fixtures/services/git.py +0 -0
  310. {xai_review-0.27.0/ai_review/tests/suites/clients/gitlab → xai_review-0.28.0/ai_review/tests/fixtures/services/review}/__init__.py +0 -0
  311. {xai_review-0.27.0/ai_review/tests/suites/clients/ollama → xai_review-0.28.0/ai_review/tests/fixtures/services/review/gateway}/__init__.py +0 -0
  312. {xai_review-0.27.0/ai_review/tests/suites/clients/openai → xai_review-0.28.0/ai_review/tests/fixtures/services/review/internal}/__init__.py +0 -0
  313. {xai_review-0.27.0/ai_review/tests/suites/libs → xai_review-0.28.0/ai_review/tests/fixtures/services/review/runner}/__init__.py +0 -0
  314. {xai_review-0.27.0/ai_review/tests/suites/libs/asynchronous → xai_review-0.28.0/ai_review/tests/suites}/__init__.py +0 -0
  315. {xai_review-0.27.0/ai_review/tests/suites/libs/config → xai_review-0.28.0/ai_review/tests/suites/cli}/__init__.py +0 -0
  316. {xai_review-0.27.0/ai_review/tests/suites/libs/diff → xai_review-0.28.0/ai_review/tests/suites/clients}/__init__.py +0 -0
  317. {xai_review-0.27.0/ai_review/tests/suites/libs/http → xai_review-0.28.0/ai_review/tests/suites/clients/bitbucket}/__init__.py +0 -0
  318. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/bitbucket/test_client.py +0 -0
  319. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/bitbucket/test_tools.py +0 -0
  320. {xai_review-0.27.0/ai_review/tests/suites/libs/template → xai_review-0.28.0/ai_review/tests/suites/clients/claude}/__init__.py +0 -0
  321. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
  322. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
  323. {xai_review-0.27.0/ai_review/tests/suites/services → xai_review-0.28.0/ai_review/tests/suites/clients/gemini}/__init__.py +0 -0
  324. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
  325. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
  326. {xai_review-0.27.0/ai_review/tests/suites/services/cost → xai_review-0.28.0/ai_review/tests/suites/clients/github}/__init__.py +0 -0
  327. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
  328. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/github/test_tools.py +0 -0
  329. {xai_review-0.27.0/ai_review/tests/suites/services/diff → xai_review-0.28.0/ai_review/tests/suites/clients/gitlab}/__init__.py +0 -0
  330. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
  331. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/gitlab/test_tools.py +0 -0
  332. {xai_review-0.27.0/ai_review/tests/suites/services/hook → xai_review-0.28.0/ai_review/tests/suites/clients/ollama}/__init__.py +0 -0
  333. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/ollama/test_client.py +0 -0
  334. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/ollama/test_schema.py +0 -0
  335. {xai_review-0.27.0/ai_review/tests/suites/services/llm → xai_review-0.28.0/ai_review/tests/suites/clients/openai}/__init__.py +0 -0
  336. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/openai/test_client.py +0 -0
  337. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/clients/openai/test_schema.py +0 -0
  338. {xai_review-0.27.0/ai_review/tests/suites/services/llm/claude → xai_review-0.28.0/ai_review/tests/suites/libs}/__init__.py +0 -0
  339. {xai_review-0.27.0/ai_review/tests/suites/services/llm/gemini → xai_review-0.28.0/ai_review/tests/suites/libs/asynchronous}/__init__.py +0 -0
  340. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
  341. {xai_review-0.27.0/ai_review/tests/suites/services/llm/ollama → xai_review-0.28.0/ai_review/tests/suites/libs/config}/__init__.py +0 -0
  342. {xai_review-0.27.0/ai_review/tests/suites/services/llm/openai → xai_review-0.28.0/ai_review/tests/suites/libs/diff}/__init__.py +0 -0
  343. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
  344. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
  345. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
  346. {xai_review-0.27.0/ai_review/tests/suites/services/prompt → xai_review-0.28.0/ai_review/tests/suites/libs/http}/__init__.py +0 -0
  347. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/http/test_paginate.py +0 -0
  348. {xai_review-0.27.0/ai_review/tests/suites/services/review → xai_review-0.28.0/ai_review/tests/suites/libs/llm}/__init__.py +0 -0
  349. {xai_review-0.27.0/ai_review/tests/suites/services/review/inline → xai_review-0.28.0/ai_review/tests/suites/libs/template}/__init__.py +0 -0
  350. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
  351. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/libs/test_json.py +0 -0
  352. {xai_review-0.27.0/ai_review/tests/suites/services/review/policy → xai_review-0.28.0/ai_review/tests/suites/services}/__init__.py +0 -0
  353. {xai_review-0.27.0/ai_review/tests/suites/services/review/summary → xai_review-0.28.0/ai_review/tests/suites/services/cost}/__init__.py +0 -0
  354. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
  355. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/cost/test_service.py +0 -0
  356. {xai_review-0.27.0/ai_review/tests/suites/services/vcs → xai_review-0.28.0/ai_review/tests/suites/services/diff}/__init__.py +0 -0
  357. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
  358. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
  359. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
  360. {xai_review-0.27.0/ai_review/tests/suites/services/vcs/bitbucket → xai_review-0.28.0/ai_review/tests/suites/services/hook}/__init__.py +0 -0
  361. {xai_review-0.27.0/ai_review/tests/suites/services/vcs/github → xai_review-0.28.0/ai_review/tests/suites/services/llm}/__init__.py +0 -0
  362. {xai_review-0.27.0/ai_review/tests/suites/services/vcs/gitlab → xai_review-0.28.0/ai_review/tests/suites/services/llm/claude}/__init__.py +0 -0
  363. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/llm/claude/test_client.py +0 -0
  364. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/llm/gemini/test_client.py +0 -0
  365. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/llm/ollama/test_client.py +0 -0
  366. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/llm/openai/test_client.py +0 -0
  367. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/llm/test_factory.py +0 -0
  368. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
  369. {xai_review-0.27.0 → xai_review-0.28.0}/ai_review/tests/suites/services/vcs/test_factory.py +0 -0
  370. {xai_review-0.27.0 → xai_review-0.28.0}/setup.cfg +0 -0
  371. {xai_review-0.27.0 → xai_review-0.28.0}/xai_review.egg-info/dependency_links.txt +0 -0
  372. {xai_review-0.27.0 → xai_review-0.28.0}/xai_review.egg-info/entry_points.txt +0 -0
  373. {xai_review-0.27.0 → xai_review-0.28.0}/xai_review.egg-info/requires.txt +0 -0
  374. {xai_review-0.27.0 → xai_review-0.28.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.27.0
3
+ Version: 0.28.0
4
4
  Summary: AI-powered code review tool
5
5
  Author-email: Nikita Filonov <nikita.filonov@example.com>
6
6
  Maintainer-email: Nikita Filonov <nikita.filonov@example.com>
@@ -69,12 +69,14 @@ improve code quality, enforce consistency, and speed up the review process.
69
69
  - **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **Ollama**, and switch anytime.
70
70
  - **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**.
71
71
  - **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
72
+ - **Reply modes** — AI can now **participate in existing review threads**, adding follow-up replies in both inline and
73
+ summary discussions.
72
74
  - **Flexible configuration** — supports `YAML`, `JSON`, and `ENV`, with seamless overrides in CI/CD pipelines.
73
75
  - **AI Review runs fully client-side** — it never proxies or inspects your requests.
74
76
 
75
- AI Review runs automatically in your CI/CD pipeline and posts both **inline comments** and **summary reviews** right
76
- inside your merge requests. This makes reviews faster, more consistent, and less error-prone — while still leaving the
77
- final decision to human reviewers.
77
+ AI Review runs automatically in your CI/CD pipeline and posts both **inline comments**, **summary reviews**, and now *
78
+ *AI-generated replies** directly inside your merge requests. This makes reviews faster, more conversational, and still
79
+ fully under human control.
78
80
 
79
81
  ---
80
82
 
@@ -209,7 +211,7 @@ jobs:
209
211
  runs-on: ubuntu-latest
210
212
  steps:
211
213
  - uses: actions/checkout@v4
212
- - uses: Nikita-Filonov/ai-review@v0.27.0
214
+ - uses: Nikita-Filonov/ai-review@v0.28.0
213
215
  with:
214
216
  review-command: ${{ inputs.review-command }}
215
217
  env:
@@ -274,6 +276,7 @@ ai-review:
274
276
  See these folders for reference templates and full configuration options:
275
277
 
276
278
  - [./docs/ci](./docs/ci) — CI/CD integration templates (GitHub Actions, GitLab CI)
279
+ - [./docs/cli](./docs/cli) — CLI command reference and usage examples
277
280
  - [./docs/hooks](./docs/hooks) — hook reference and lifecycle events
278
281
  - [./docs/configs](./docs/configs) — full configuration examples (`.yaml`, `.json`, `.env`)
279
282
  - [./docs/prompts](./docs/prompts) — prompt templates for Python/Go (light & strict modes)
@@ -35,12 +35,14 @@ improve code quality, enforce consistency, and speed up the review process.
35
35
  - **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **Ollama**, and switch anytime.
36
36
  - **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**.
37
37
  - **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
38
+ - **Reply modes** — AI can now **participate in existing review threads**, adding follow-up replies in both inline and
39
+ summary discussions.
38
40
  - **Flexible configuration** — supports `YAML`, `JSON`, and `ENV`, with seamless overrides in CI/CD pipelines.
39
41
  - **AI Review runs fully client-side** — it never proxies or inspects your requests.
40
42
 
41
- AI Review runs automatically in your CI/CD pipeline and posts both **inline comments** and **summary reviews** right
42
- inside your merge requests. This makes reviews faster, more consistent, and less error-prone — while still leaving the
43
- final decision to human reviewers.
43
+ AI Review runs automatically in your CI/CD pipeline and posts both **inline comments**, **summary reviews**, and now *
44
+ *AI-generated replies** directly inside your merge requests. This makes reviews faster, more conversational, and still
45
+ fully under human control.
44
46
 
45
47
  ---
46
48
 
@@ -175,7 +177,7 @@ jobs:
175
177
  runs-on: ubuntu-latest
176
178
  steps:
177
179
  - uses: actions/checkout@v4
178
- - uses: Nikita-Filonov/ai-review@v0.27.0
180
+ - uses: Nikita-Filonov/ai-review@v0.28.0
179
181
  with:
180
182
  review-command: ${{ inputs.review-command }}
181
183
  env:
@@ -240,6 +242,7 @@ ai-review:
240
242
  See these folders for reference templates and full configuration options:
241
243
 
242
244
  - [./docs/ci](./docs/ci) — CI/CD integration templates (GitHub Actions, GitLab CI)
245
+ - [./docs/cli](./docs/cli) — CLI command reference and usage examples
243
246
  - [./docs/hooks](./docs/hooks) — hook reference and lifecycle events
244
247
  - [./docs/configs](./docs/configs) — full configuration examples (`.yaml`, `.json`, `.env`)
245
248
  - [./docs/prompts](./docs/prompts) — prompt templates for Python/Go (light & strict modes)
@@ -0,0 +1,7 @@
1
+ from ai_review.services.review.service import ReviewService
2
+
3
+
4
+ async def run_inline_reply_review_command():
5
+ review_service = ReviewService()
6
+ await review_service.run_inline_reply_review()
7
+ review_service.report_total_cost()
@@ -0,0 +1,7 @@
1
+ from ai_review.services.review.service import ReviewService
2
+
3
+
4
+ async def run_summary_reply_review_command():
5
+ review_service = ReviewService()
6
+ await review_service.run_summary_reply_review()
7
+ review_service.report_total_cost()
@@ -3,8 +3,10 @@ import asyncio
3
3
  import typer
4
4
 
5
5
  from ai_review.cli.commands.run_context_review import run_context_review_command
6
+ from ai_review.cli.commands.run_inline_reply_review import run_inline_reply_review_command
6
7
  from ai_review.cli.commands.run_inline_review import run_inline_review_command
7
8
  from ai_review.cli.commands.run_review import run_review_command
9
+ from ai_review.cli.commands.run_summary_reply_review import run_summary_reply_review_command
8
10
  from ai_review.cli.commands.run_summary_review import run_summary_review_command
9
11
  from ai_review.config import settings
10
12
 
@@ -43,6 +45,21 @@ def run_summary():
43
45
  typer.secho("AI review completed successfully!", fg=typer.colors.GREEN, bold=True)
44
46
 
45
47
 
48
+ @app.command("run-inline-reply")
49
+ def run_inline_reply():
50
+ """Run only the inline reply review"""
51
+ typer.secho("Starting inline reply AI review...", fg=typer.colors.CYAN)
52
+ asyncio.run(run_inline_reply_review_command())
53
+ typer.secho("AI review completed successfully!", fg=typer.colors.GREEN, bold=True)
54
+
55
+
56
+ @app.command("run-summary-reply")
57
+ def run_summary_reply():
58
+ typer.secho("Starting summary reply AI review...", fg=typer.colors.CYAN)
59
+ asyncio.run(run_summary_reply_review_command())
60
+ typer.secho("AI review completed successfully!", fg=typer.colors.GREEN, bold=True)
61
+
62
+
46
63
  @app.command("show-config")
47
64
  def show_config():
48
65
  """Show the current resolved configuration"""
@@ -1,5 +1,7 @@
1
1
  from pydantic import BaseModel, Field, ConfigDict
2
2
 
3
+ from ai_review.clients.bitbucket.pr.schema.user import BitbucketUserSchema
4
+
3
5
 
4
6
  class BitbucketCommentContentSchema(BaseModel):
5
7
  raw: str
@@ -15,8 +17,14 @@ class BitbucketCommentInlineSchema(BaseModel):
15
17
  from_line: int | None = Field(alias="from", default=None)
16
18
 
17
19
 
20
+ class BitbucketCommentParentSchema(BaseModel):
21
+ id: int
22
+
23
+
18
24
  class BitbucketPRCommentSchema(BaseModel):
19
25
  id: int
26
+ user: BitbucketUserSchema | None = None
27
+ parent: BitbucketCommentParentSchema | None = None
20
28
  inline: BitbucketCommentInlineSchema | None = None
21
29
  content: BitbucketCommentContentSchema
22
30
 
@@ -38,12 +46,18 @@ class BitbucketGetPRCommentsResponseSchema(BaseModel):
38
46
  page_len: int = Field(alias="pagelen")
39
47
 
40
48
 
49
+ class BitbucketParentSchema(BaseModel):
50
+ id: int
51
+
52
+
41
53
  class BitbucketCreatePRCommentRequestSchema(BaseModel):
54
+ parent: BitbucketParentSchema | None = None
42
55
  inline: BitbucketCommentInlineSchema | None = None
43
56
  content: BitbucketCommentContentSchema
44
57
 
45
58
 
46
59
  class BitbucketCreatePRCommentResponseSchema(BaseModel):
47
60
  id: int
61
+ parent: BitbucketParentSchema | None = None
48
62
  inline: BitbucketCommentInlineSchema | None = None
49
63
  content: BitbucketCommentContentSchema
@@ -1,10 +1,6 @@
1
1
  from pydantic import BaseModel, Field
2
2
 
3
-
4
- class BitbucketUserSchema(BaseModel):
5
- uuid: str
6
- nickname: str
7
- display_name: str
3
+ from ai_review.clients.bitbucket.pr.schema.user import BitbucketUserSchema
8
4
 
9
5
 
10
6
  class BitbucketBranchSchema(BaseModel):
@@ -0,0 +1,7 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class BitbucketUserSchema(BaseModel):
5
+ uuid: str
6
+ nickname: str
7
+ display_name: str
@@ -2,10 +2,13 @@ from httpx import Response, QueryParams
2
2
 
3
3
  from ai_review.clients.github.pr.schema.comments import (
4
4
  GitHubPRCommentSchema,
5
+ GitHubIssueCommentSchema,
5
6
  GitHubGetPRCommentsQuerySchema,
6
7
  GitHubGetPRCommentsResponseSchema,
8
+ GitHubGetIssueCommentsResponseSchema,
7
9
  GitHubCreateIssueCommentRequestSchema,
8
10
  GitHubCreateIssueCommentResponseSchema,
11
+ GitHubCreateReviewReplyRequestSchema,
9
12
  GitHubCreateReviewCommentRequestSchema,
10
13
  GitHubCreateReviewCommentResponseSchema
11
14
  )
@@ -76,6 +79,19 @@ class GitHubPullRequestsHTTPClient(HTTPClient, GitHubPullRequestsHTTPClientProto
76
79
  query=QueryParams(**query.model_dump())
77
80
  )
78
81
 
82
+ @handle_http_error(client="GitHubPullRequestsHTTPClient", exception=GitHubPullRequestsHTTPClientError)
83
+ async def create_review_reply_api(
84
+ self,
85
+ owner: str,
86
+ repo: str,
87
+ pull_number: str,
88
+ request: GitHubCreateReviewReplyRequestSchema,
89
+ ) -> Response:
90
+ return await self.post(
91
+ f"/repos/{owner}/{repo}/pulls/{pull_number}/comments",
92
+ json=request.model_dump(),
93
+ )
94
+
79
95
  @handle_http_error(client="GitHubPullRequestsHTTPClient", exception=GitHubPullRequestsHTTPClientError)
80
96
  async def create_review_comment_api(
81
97
  self,
@@ -136,13 +152,18 @@ class GitHubPullRequestsHTTPClient(HTTPClient, GitHubPullRequestsHTTPClientProto
136
152
  )
137
153
  return GitHubGetPRFilesResponseSchema(root=items)
138
154
 
139
- async def get_issue_comments(self, owner: str, repo: str, issue_number: str) -> GitHubGetPRCommentsResponseSchema:
155
+ async def get_issue_comments(
156
+ self,
157
+ owner: str,
158
+ repo: str,
159
+ issue_number: str
160
+ ) -> GitHubGetIssueCommentsResponseSchema:
140
161
  async def fetch_page(page: int) -> Response:
141
162
  query = GitHubGetPRCommentsQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
142
163
  return await self.get_issue_comments_api(owner, repo, issue_number, query)
143
164
 
144
- def extract_items(response: Response) -> list[GitHubPRCommentSchema]:
145
- result = GitHubGetPRCommentsResponseSchema.model_validate_json(response.text)
165
+ def extract_items(response: Response) -> list[GitHubIssueCommentSchema]:
166
+ result = GitHubGetIssueCommentsResponseSchema.model_validate_json(response.text)
146
167
  return result.root
147
168
 
148
169
  items = await paginate(
@@ -151,7 +172,7 @@ class GitHubPullRequestsHTTPClient(HTTPClient, GitHubPullRequestsHTTPClientProto
151
172
  extract_items=extract_items,
152
173
  has_next_page=github_has_next_page
153
174
  )
154
- return GitHubGetPRCommentsResponseSchema(root=items)
175
+ return GitHubGetIssueCommentsResponseSchema(root=items)
155
176
 
156
177
  async def get_review_comments(self, owner: str, repo: str, pull_number: str) -> GitHubGetPRCommentsResponseSchema:
157
178
  async def fetch_page(page: int) -> Response:
@@ -187,6 +208,16 @@ class GitHubPullRequestsHTTPClient(HTTPClient, GitHubPullRequestsHTTPClientProto
187
208
  )
188
209
  return GitHubGetPRReviewsResponseSchema(root=items)
189
210
 
211
+ async def create_review_reply(
212
+ self,
213
+ owner: str,
214
+ repo: str,
215
+ pull_number: str,
216
+ request: GitHubCreateReviewReplyRequestSchema,
217
+ ) -> GitHubCreateReviewCommentResponseSchema:
218
+ response = await self.create_review_reply_api(owner, repo, pull_number, request)
219
+ return GitHubCreateReviewCommentResponseSchema.model_validate_json(response.text)
220
+
190
221
  async def create_review_comment(
191
222
  self,
192
223
  owner: str,
@@ -1,11 +1,23 @@
1
1
  from pydantic import BaseModel, RootModel
2
2
 
3
+ from ai_review.clients.github.pr.schema.user import GitHubUserSchema
4
+
5
+
6
+ class GitHubIssueCommentSchema(BaseModel):
7
+ """Represents a top-level comment in a PR discussion (issue-level)."""
8
+ id: int
9
+ body: str
10
+ user: GitHubUserSchema | None = None
11
+
3
12
 
4
13
  class GitHubPRCommentSchema(BaseModel):
14
+ """Represents an inline code review comment on a specific line in a PR."""
5
15
  id: int
6
16
  body: str
7
17
  path: str | None = None
8
18
  line: int | None = None
19
+ user: GitHubUserSchema | None = None
20
+ in_reply_to_id: int | None = None
9
21
 
10
22
 
11
23
  class GitHubGetPRCommentsQuerySchema(BaseModel):
@@ -17,6 +29,10 @@ class GitHubGetPRCommentsResponseSchema(RootModel[list[GitHubPRCommentSchema]]):
17
29
  root: list[GitHubPRCommentSchema]
18
30
 
19
31
 
32
+ class GitHubGetIssueCommentsResponseSchema(RootModel[list[GitHubIssueCommentSchema]]):
33
+ root: list[GitHubIssueCommentSchema]
34
+
35
+
20
36
  class GitHubCreateIssueCommentRequestSchema(BaseModel):
21
37
  body: str
22
38
 
@@ -26,6 +42,11 @@ class GitHubCreateIssueCommentResponseSchema(BaseModel):
26
42
  body: str
27
43
 
28
44
 
45
+ class GitHubCreateReviewReplyRequestSchema(BaseModel):
46
+ body: str
47
+ in_reply_to: int
48
+
49
+
29
50
  class GitHubCreateReviewCommentRequestSchema(BaseModel):
30
51
  body: str
31
52
  path: str
@@ -1,9 +1,6 @@
1
1
  from pydantic import BaseModel, Field
2
2
 
3
-
4
- class GitHubUserSchema(BaseModel):
5
- id: int
6
- login: str
3
+ from ai_review.clients.github.pr.schema.user import GitHubUserSchema
7
4
 
8
5
 
9
6
  class GitHubLabelSchema(BaseModel):
@@ -0,0 +1,6 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class GitHubUserSchema(BaseModel):
5
+ id: int | None = None
6
+ login: str
@@ -2,7 +2,9 @@ from typing import Protocol
2
2
 
3
3
  from ai_review.clients.github.pr.schema.comments import (
4
4
  GitHubGetPRCommentsResponseSchema,
5
+ GitHubGetIssueCommentsResponseSchema,
5
6
  GitHubCreateIssueCommentResponseSchema,
7
+ GitHubCreateReviewReplyRequestSchema,
6
8
  GitHubCreateReviewCommentResponseSchema,
7
9
  GitHubCreateReviewCommentRequestSchema,
8
10
  )
@@ -21,7 +23,7 @@ class GitHubPullRequestsHTTPClientProtocol(Protocol):
21
23
  owner: str,
22
24
  repo: str,
23
25
  issue_number: str
24
- ) -> GitHubGetPRCommentsResponseSchema: ...
26
+ ) -> GitHubGetIssueCommentsResponseSchema: ...
25
27
 
26
28
  async def get_review_comments(
27
29
  self,
@@ -32,6 +34,14 @@ class GitHubPullRequestsHTTPClientProtocol(Protocol):
32
34
 
33
35
  async def get_reviews(self, owner: str, repo: str, pull_number: str) -> GitHubGetPRReviewsResponseSchema: ...
34
36
 
37
+ async def create_review_reply(
38
+ self,
39
+ owner: str,
40
+ repo: str,
41
+ comment_id: str,
42
+ request: GitHubCreateReviewReplyRequestSchema,
43
+ ) -> GitHubCreateReviewCommentResponseSchema: ...
44
+
35
45
  async def create_review_comment(
36
46
  self,
37
47
  owner: str,
@@ -6,7 +6,9 @@ from ai_review.clients.gitlab.mr.schema.discussions import (
6
6
  GitLabGetMRDiscussionsQuerySchema,
7
7
  GitLabGetMRDiscussionsResponseSchema,
8
8
  GitLabCreateMRDiscussionRequestSchema,
9
- GitLabCreateMRDiscussionResponseSchema
9
+ GitLabCreateMRDiscussionResponseSchema,
10
+ GitLabCreateMRDiscussionReplyRequestSchema,
11
+ GitLabCreateMRDiscussionReplyResponseSchema
10
12
  )
11
13
  from ai_review.clients.gitlab.mr.schema.notes import (
12
14
  GitLabNoteSchema,
@@ -82,6 +84,19 @@ class GitLabMergeRequestsHTTPClient(HTTPClient, GitLabMergeRequestsHTTPClientPro
82
84
  json=request.model_dump(),
83
85
  )
84
86
 
87
+ @handle_http_error(client="GitLabMergeRequestsHTTPClient", exception=GitLabMergeRequestsHTTPClientError)
88
+ async def create_discussion_reply_api(
89
+ self,
90
+ project_id: str,
91
+ merge_request_id: str,
92
+ discussion_id: str,
93
+ request: GitLabCreateMRDiscussionReplyRequestSchema,
94
+ ) -> Response:
95
+ return await self.post(
96
+ f"/api/v4/projects/{project_id}/merge_requests/{merge_request_id}/discussions/{discussion_id}/notes",
97
+ json=request.model_dump(),
98
+ )
99
+
85
100
  async def get_changes(self, project_id: str, merge_request_id: str) -> GitLabGetMRChangesResponseSchema:
86
101
  response = await self.get_changes_api(project_id, merge_request_id)
87
102
  return GitLabGetMRChangesResponseSchema.model_validate_json(response.text)
@@ -154,3 +169,19 @@ class GitLabMergeRequestsHTTPClient(HTTPClient, GitLabMergeRequestsHTTPClientPro
154
169
  merge_request_id=merge_request_id
155
170
  )
156
171
  return GitLabCreateMRDiscussionResponseSchema.model_validate_json(response.text)
172
+
173
+ async def create_discussion_reply(
174
+ self,
175
+ project_id: str,
176
+ merge_request_id: str,
177
+ discussion_id: str,
178
+ body: str,
179
+ ) -> GitLabCreateMRDiscussionReplyResponseSchema:
180
+ request = GitLabCreateMRDiscussionReplyRequestSchema(body=body)
181
+ response = await self.create_discussion_reply_api(
182
+ project_id=project_id,
183
+ merge_request_id=merge_request_id,
184
+ discussion_id=discussion_id,
185
+ request=request,
186
+ )
187
+ return GitLabCreateMRDiscussionReplyResponseSchema.model_validate_json(response.text)
@@ -1,10 +1,6 @@
1
1
  from pydantic import BaseModel, Field
2
2
 
3
-
4
- class GitLabUserSchema(BaseModel):
5
- id: int
6
- name: str
7
- username: str
3
+ from ai_review.clients.gitlab.mr.schema.user import GitLabUserSchema
8
4
 
9
5
 
10
6
  class GitLabDiffRefsSchema(BaseModel):
@@ -1,13 +1,8 @@
1
- from pydantic import BaseModel, RootModel
1
+ from pydantic import BaseModel, RootModel, Field
2
2
 
3
3
  from ai_review.clients.gitlab.mr.schema.notes import GitLabNoteSchema
4
4
 
5
5
 
6
- class GitLabDiscussionSchema(BaseModel):
7
- id: str
8
- notes: list[GitLabNoteSchema]
9
-
10
-
11
6
  class GitLabDiscussionPositionSchema(BaseModel):
12
7
  position_type: str = "text"
13
8
  base_sha: str
@@ -17,6 +12,12 @@ class GitLabDiscussionPositionSchema(BaseModel):
17
12
  new_line: int
18
13
 
19
14
 
15
+ class GitLabDiscussionSchema(BaseModel):
16
+ id: str
17
+ notes: list[GitLabNoteSchema]
18
+ position: GitLabDiscussionPositionSchema | None = None
19
+
20
+
20
21
  class GitLabGetMRDiscussionsQuerySchema(BaseModel):
21
22
  page: int = 1
22
23
  per_page: int = 100
@@ -33,4 +34,13 @@ class GitLabCreateMRDiscussionRequestSchema(BaseModel):
33
34
 
34
35
  class GitLabCreateMRDiscussionResponseSchema(BaseModel):
35
36
  id: str
36
- body: str | None = None
37
+ notes: list[GitLabNoteSchema] = Field(default_factory=list)
38
+
39
+
40
+ class GitLabCreateMRDiscussionReplyRequestSchema(BaseModel):
41
+ body: str
42
+
43
+
44
+ class GitLabCreateMRDiscussionReplyResponseSchema(BaseModel):
45
+ id: int
46
+ body: str
@@ -1,9 +1,12 @@
1
1
  from pydantic import BaseModel, RootModel
2
2
 
3
+ from ai_review.clients.gitlab.mr.schema.user import GitLabUserSchema
4
+
3
5
 
4
6
  class GitLabNoteSchema(BaseModel):
5
7
  id: int
6
8
  body: str
9
+ author: GitLabUserSchema | None = None
7
10
 
8
11
 
9
12
  class GitLabGetMRNotesQuerySchema(BaseModel):
@@ -0,0 +1,7 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class GitLabUserSchema(BaseModel):
5
+ id: int
6
+ name: str
7
+ username: str
@@ -3,8 +3,9 @@ from typing import Protocol
3
3
  from ai_review.clients.gitlab.mr.schema.changes import GitLabGetMRChangesResponseSchema
4
4
  from ai_review.clients.gitlab.mr.schema.discussions import (
5
5
  GitLabGetMRDiscussionsResponseSchema,
6
- GitLabCreateMRDiscussionResponseSchema,
7
6
  GitLabCreateMRDiscussionRequestSchema,
7
+ GitLabCreateMRDiscussionResponseSchema,
8
+ GitLabCreateMRDiscussionReplyResponseSchema
8
9
  )
9
10
  from ai_review.clients.gitlab.mr.schema.notes import GitLabGetMRNotesResponseSchema, GitLabCreateMRNoteResponseSchema
10
11
 
@@ -14,12 +15,6 @@ class GitLabMergeRequestsHTTPClientProtocol(Protocol):
14
15
 
15
16
  async def get_notes(self, project_id: str, merge_request_id: str) -> GitLabGetMRNotesResponseSchema: ...
16
17
 
17
- async def get_discussions(
18
- self,
19
- project_id: str,
20
- merge_request_id: str
21
- ) -> GitLabGetMRDiscussionsResponseSchema: ...
22
-
23
18
  async def create_note(
24
19
  self,
25
20
  body: str,
@@ -27,9 +22,23 @@ class GitLabMergeRequestsHTTPClientProtocol(Protocol):
27
22
  merge_request_id: str,
28
23
  ) -> GitLabCreateMRNoteResponseSchema: ...
29
24
 
25
+ async def get_discussions(
26
+ self,
27
+ project_id: str,
28
+ merge_request_id: str
29
+ ) -> GitLabGetMRDiscussionsResponseSchema: ...
30
+
30
31
  async def create_discussion(
31
32
  self,
32
33
  project_id: str,
33
34
  merge_request_id: str,
34
35
  request: GitLabCreateMRDiscussionRequestSchema,
35
36
  ) -> GitLabCreateMRDiscussionResponseSchema: ...
37
+
38
+ async def create_discussion_reply(
39
+ self,
40
+ project_id: str,
41
+ merge_request_id: str,
42
+ discussion_id: str,
43
+ body: str,
44
+ ) -> GitLabCreateMRDiscussionReplyResponseSchema: ...