xai-review 0.27.0__py3-none-any.whl → 0.28.0__py3-none-any.whl

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 (147) hide show
  1. ai_review/cli/commands/run_inline_reply_review.py +7 -0
  2. ai_review/cli/commands/run_summary_reply_review.py +7 -0
  3. ai_review/cli/main.py +17 -0
  4. ai_review/clients/bitbucket/pr/schema/comments.py +14 -0
  5. ai_review/clients/bitbucket/pr/schema/pull_request.py +1 -5
  6. ai_review/clients/bitbucket/pr/schema/user.py +7 -0
  7. ai_review/clients/github/pr/client.py +35 -4
  8. ai_review/clients/github/pr/schema/comments.py +21 -0
  9. ai_review/clients/github/pr/schema/pull_request.py +1 -4
  10. ai_review/clients/github/pr/schema/user.py +6 -0
  11. ai_review/clients/github/pr/types.py +11 -1
  12. ai_review/clients/gitlab/mr/client.py +32 -1
  13. ai_review/clients/gitlab/mr/schema/changes.py +1 -5
  14. ai_review/clients/gitlab/mr/schema/discussions.py +17 -7
  15. ai_review/clients/gitlab/mr/schema/notes.py +3 -0
  16. ai_review/clients/gitlab/mr/schema/user.py +7 -0
  17. ai_review/clients/gitlab/mr/types.py +16 -7
  18. ai_review/libs/config/prompt.py +96 -64
  19. ai_review/libs/config/review.py +2 -0
  20. ai_review/libs/llm/output_json_parser.py +60 -0
  21. ai_review/prompts/default_inline_reply.md +10 -0
  22. ai_review/prompts/default_summary_reply.md +14 -0
  23. ai_review/prompts/default_system_inline_reply.md +31 -0
  24. ai_review/prompts/default_system_summary_reply.md +13 -0
  25. ai_review/services/artifacts/schema.py +2 -2
  26. ai_review/services/hook/constants.py +14 -0
  27. ai_review/services/hook/service.py +95 -4
  28. ai_review/services/hook/types.py +18 -2
  29. ai_review/services/prompt/adapter.py +1 -1
  30. ai_review/services/prompt/service.py +49 -3
  31. ai_review/services/prompt/tools.py +21 -0
  32. ai_review/services/prompt/types.py +23 -0
  33. ai_review/services/review/gateway/comment.py +45 -6
  34. ai_review/services/review/gateway/llm.py +2 -1
  35. ai_review/services/review/gateway/types.py +50 -0
  36. ai_review/services/review/internal/inline/service.py +40 -0
  37. ai_review/services/review/internal/inline/types.py +8 -0
  38. ai_review/services/review/internal/inline_reply/schema.py +23 -0
  39. ai_review/services/review/internal/inline_reply/service.py +20 -0
  40. ai_review/services/review/internal/inline_reply/types.py +8 -0
  41. ai_review/services/review/{policy → internal/policy}/service.py +2 -1
  42. ai_review/services/review/internal/policy/types.py +15 -0
  43. ai_review/services/review/{summary → internal/summary}/service.py +2 -2
  44. ai_review/services/review/{summary → internal/summary}/types.py +1 -1
  45. ai_review/services/review/internal/summary_reply/__init__.py +0 -0
  46. ai_review/services/review/internal/summary_reply/schema.py +8 -0
  47. ai_review/services/review/internal/summary_reply/service.py +15 -0
  48. ai_review/services/review/internal/summary_reply/types.py +8 -0
  49. ai_review/services/review/runner/__init__.py +0 -0
  50. ai_review/services/review/runner/context.py +72 -0
  51. ai_review/services/review/runner/inline.py +80 -0
  52. ai_review/services/review/runner/inline_reply.py +80 -0
  53. ai_review/services/review/runner/summary.py +71 -0
  54. ai_review/services/review/runner/summary_reply.py +79 -0
  55. ai_review/services/review/runner/types.py +6 -0
  56. ai_review/services/review/service.py +78 -110
  57. ai_review/services/vcs/bitbucket/adapter.py +24 -0
  58. ai_review/services/vcs/bitbucket/client.py +107 -42
  59. ai_review/services/vcs/github/adapter.py +35 -0
  60. ai_review/services/vcs/github/client.py +105 -44
  61. ai_review/services/vcs/gitlab/adapter.py +26 -0
  62. ai_review/services/vcs/gitlab/client.py +91 -38
  63. ai_review/services/vcs/types.py +34 -0
  64. ai_review/tests/fixtures/clients/bitbucket.py +2 -2
  65. ai_review/tests/fixtures/clients/github.py +35 -6
  66. ai_review/tests/fixtures/clients/gitlab.py +42 -3
  67. ai_review/tests/fixtures/libs/__init__.py +0 -0
  68. ai_review/tests/fixtures/libs/llm/__init__.py +0 -0
  69. ai_review/tests/fixtures/libs/llm/output_json_parser.py +13 -0
  70. ai_review/tests/fixtures/services/hook.py +8 -0
  71. ai_review/tests/fixtures/services/llm.py +8 -5
  72. ai_review/tests/fixtures/services/prompt.py +70 -0
  73. ai_review/tests/fixtures/services/review/base.py +41 -0
  74. ai_review/tests/fixtures/services/review/gateway/__init__.py +0 -0
  75. ai_review/tests/fixtures/services/review/gateway/comment.py +98 -0
  76. ai_review/tests/fixtures/services/review/gateway/llm.py +17 -0
  77. ai_review/tests/fixtures/services/review/internal/__init__.py +0 -0
  78. ai_review/tests/fixtures/services/review/{inline.py → internal/inline.py} +8 -6
  79. ai_review/tests/fixtures/services/review/internal/inline_reply.py +25 -0
  80. ai_review/tests/fixtures/services/review/internal/policy.py +28 -0
  81. ai_review/tests/fixtures/services/review/internal/summary.py +21 -0
  82. ai_review/tests/fixtures/services/review/internal/summary_reply.py +19 -0
  83. ai_review/tests/fixtures/services/review/runner/__init__.py +0 -0
  84. ai_review/tests/fixtures/services/review/runner/context.py +50 -0
  85. ai_review/tests/fixtures/services/review/runner/inline.py +50 -0
  86. ai_review/tests/fixtures/services/review/runner/inline_reply.py +50 -0
  87. ai_review/tests/fixtures/services/review/runner/summary.py +50 -0
  88. ai_review/tests/fixtures/services/review/runner/summary_reply.py +50 -0
  89. ai_review/tests/fixtures/services/vcs.py +23 -0
  90. ai_review/tests/suites/cli/__init__.py +0 -0
  91. ai_review/tests/suites/cli/test_main.py +54 -0
  92. ai_review/tests/suites/libs/config/test_prompt.py +108 -28
  93. ai_review/tests/suites/libs/llm/__init__.py +0 -0
  94. ai_review/tests/suites/libs/llm/test_output_json_parser.py +155 -0
  95. ai_review/tests/suites/services/hook/test_service.py +88 -4
  96. ai_review/tests/suites/services/prompt/test_adapter.py +3 -3
  97. ai_review/tests/suites/services/prompt/test_service.py +102 -58
  98. ai_review/tests/suites/services/prompt/test_tools.py +86 -1
  99. ai_review/tests/suites/services/review/gateway/__init__.py +0 -0
  100. ai_review/tests/suites/services/review/gateway/test_comment.py +253 -0
  101. ai_review/tests/suites/services/review/gateway/test_llm.py +82 -0
  102. ai_review/tests/suites/services/review/internal/__init__.py +0 -0
  103. ai_review/tests/suites/services/review/internal/inline/__init__.py +0 -0
  104. ai_review/tests/suites/services/review/{inline → internal/inline}/test_schema.py +1 -1
  105. ai_review/tests/suites/services/review/internal/inline/test_service.py +81 -0
  106. ai_review/tests/suites/services/review/internal/inline_reply/__init__.py +0 -0
  107. ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py +57 -0
  108. ai_review/tests/suites/services/review/internal/inline_reply/test_service.py +72 -0
  109. ai_review/tests/suites/services/review/internal/policy/__init__.py +0 -0
  110. ai_review/tests/suites/services/review/{policy → internal/policy}/test_service.py +1 -1
  111. ai_review/tests/suites/services/review/internal/summary/__init__.py +0 -0
  112. ai_review/tests/suites/services/review/{summary → internal/summary}/test_schema.py +1 -1
  113. ai_review/tests/suites/services/review/{summary → internal/summary}/test_service.py +2 -2
  114. ai_review/tests/suites/services/review/internal/summary_reply/__init__.py +0 -0
  115. ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py +19 -0
  116. ai_review/tests/suites/services/review/internal/summary_reply/test_service.py +21 -0
  117. ai_review/tests/suites/services/review/runner/__init__.py +0 -0
  118. ai_review/tests/suites/services/review/runner/test_context.py +89 -0
  119. ai_review/tests/suites/services/review/runner/test_inline.py +100 -0
  120. ai_review/tests/suites/services/review/runner/test_inline_reply.py +109 -0
  121. ai_review/tests/suites/services/review/runner/test_summary.py +87 -0
  122. ai_review/tests/suites/services/review/runner/test_summary_reply.py +97 -0
  123. ai_review/tests/suites/services/review/test_service.py +64 -97
  124. ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py +109 -0
  125. ai_review/tests/suites/services/vcs/bitbucket/{test_service.py → test_client.py} +88 -1
  126. ai_review/tests/suites/services/vcs/github/test_adapter.py +162 -0
  127. ai_review/tests/suites/services/vcs/github/{test_service.py → test_client.py} +102 -2
  128. ai_review/tests/suites/services/vcs/gitlab/test_adapter.py +105 -0
  129. ai_review/tests/suites/services/vcs/gitlab/{test_service.py → test_client.py} +99 -1
  130. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/METADATA +8 -5
  131. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/RECORD +143 -70
  132. ai_review/services/review/inline/service.py +0 -54
  133. ai_review/services/review/inline/types.py +0 -11
  134. ai_review/tests/fixtures/services/review/summary.py +0 -19
  135. ai_review/tests/suites/services/review/inline/test_service.py +0 -107
  136. /ai_review/{services/review/inline → libs/llm}/__init__.py +0 -0
  137. /ai_review/services/review/{policy → internal}/__init__.py +0 -0
  138. /ai_review/services/review/{summary → internal/inline}/__init__.py +0 -0
  139. /ai_review/services/review/{inline → internal/inline}/schema.py +0 -0
  140. /ai_review/{tests/suites/services/review/inline → services/review/internal/inline_reply}/__init__.py +0 -0
  141. /ai_review/{tests/suites/services/review → services/review/internal}/policy/__init__.py +0 -0
  142. /ai_review/{tests/suites/services/review → services/review/internal}/summary/__init__.py +0 -0
  143. /ai_review/services/review/{summary → internal/summary}/schema.py +0 -0
  144. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/WHEEL +0 -0
  145. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/entry_points.txt +0 -0
  146. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/licenses/LICENSE +0 -0
  147. {xai_review-0.27.0.dist-info → xai_review-0.28.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,13 @@
1
1
  ai_review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  ai_review/config.py,sha256=LmHYNW44hi9qUhGxUjwoZBNrfu49-TcZD7WyGpfbpPI,1964
3
3
  ai_review/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- ai_review/cli/main.py,sha256=rZ0LYSAt3AFT-wOHdop8lq2GOVAK48kJYp7nf801Mjs,1854
4
+ ai_review/cli/main.py,sha256=ARkyuafiDutE259idnnYtcTyTvB84WLAklFCNDmJ-l0,2631
5
5
  ai_review/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  ai_review/cli/commands/run_context_review.py,sha256=pWYv9fIlVql8Bf0oz4UQ0a-Ta5NCzY3hC7f_W23wUaA,224
7
+ ai_review/cli/commands/run_inline_reply_review.py,sha256=p10zWOeAInta_tVIbp4Rxo2hnHvPV1RtNl3TbELLIY4,234
7
8
  ai_review/cli/commands/run_inline_review.py,sha256=u55K-Su0PR2-NcK7XI2rTCIi7HTEi1VvA8wyw2B39bk,222
8
9
  ai_review/cli/commands/run_review.py,sha256=i39IYNDE_lAiQQnKLmxG71Ao8WAIOSn82L9EpdbPcsI,261
10
+ ai_review/cli/commands/run_summary_reply_review.py,sha256=xtrKM1-E4-0P1jpO8mZ6LTGAdEW1q6Df9C6nUcvOywo,236
9
11
  ai_review/cli/commands/run_summary_review.py,sha256=NqjepGH5cbqczPzcuMEAxO4dI58FEUZl0b6uRVQ9SiA,224
10
12
  ai_review/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
13
  ai_review/clients/bitbucket/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -15,9 +17,10 @@ ai_review/clients/bitbucket/pr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
15
17
  ai_review/clients/bitbucket/pr/client.py,sha256=YnA5GCw_qqrjraNH_LjtE7t7cCmrMTY9IrcxDT2uyZ0,5836
16
18
  ai_review/clients/bitbucket/pr/types.py,sha256=ZICV4ghYChj1Jl9Nlwyw1_kwmGybX51GhGdGzkRaLCk,1296
17
19
  ai_review/clients/bitbucket/pr/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- ai_review/clients/bitbucket/pr/schema/comments.py,sha256=p3HQyi-M7DLXcD0RErVlqsnKhmo2JVqdA8ejVYF_Kzg,1337
20
+ ai_review/clients/bitbucket/pr/schema/comments.py,sha256=V8NlIPGGWbziF4EZoTH7zHtnI9rauu1mjqdNvCku-5E,1723
19
21
  ai_review/clients/bitbucket/pr/schema/files.py,sha256=qBDfIv370TDMKM8yoLlm1c-BTHNvEZRuhnBo18nkx9g,750
20
- ai_review/clients/bitbucket/pr/schema/pull_request.py,sha256=buGULgaCkxCUFSdiw0XTwaSIYP_p1rAEuKXUyJ_Mzi8,863
22
+ ai_review/clients/bitbucket/pr/schema/pull_request.py,sha256=Eq8huJmZ9smy2JlsPuMF-Vv8EmHYR3rFQ_5EFVc2QRc,845
23
+ ai_review/clients/bitbucket/pr/schema/user.py,sha256=-TsvtifDNZSK82fqNXv6N3li2hnui1_9g2ugSBx4Ibs,125
21
24
  ai_review/clients/claude/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
25
  ai_review/clients/claude/client.py,sha256=uEadbBNBJnzjHDczbxXiiw1V1H1PdUWKu-Gn-eIDEmw,1890
23
26
  ai_review/clients/claude/schema.py,sha256=LE6KCjJKDXqBGU2Cno5XL5R8vUfScgskE9MqvE0Pt2A,887
@@ -30,23 +33,25 @@ ai_review/clients/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
30
33
  ai_review/clients/github/client.py,sha256=pprQcCYdrhRYtuqRsTFiCbj54Qb1Ll6_jmlm7AJg8pk,1149
31
34
  ai_review/clients/github/tools.py,sha256=sD2eS_iNhzT4ZLgTRmO2uBLuId-fa2aSvbu6VFeKSlc,201
32
35
  ai_review/clients/github/pr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- ai_review/clients/github/pr/client.py,sha256=HysL1u-WxLdhGKi-6HAx6fN-50XSk3yK55gZ9Nii72U,8851
34
- ai_review/clients/github/pr/types.py,sha256=mI5Vtlxc25iymOTPkNl55IQygXd4ti3B1Ydpx3q1fps,1726
36
+ ai_review/clients/github/pr/client.py,sha256=f9wYQq-zIbfFBkEEDLDWg0woKAXFoM9GjiO5X3WBL08,9918
37
+ ai_review/clients/github/pr/types.py,sha256=vASMTJBecoJQXe7Y5kHkQ0fsQms19S74SqfBcyrhN9M,2056
35
38
  ai_review/clients/github/pr/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- ai_review/clients/github/pr/schema/comments.py,sha256=dIlX6tYPseAtLquk-UIie7jxBxrCbmPbDyB8bC9OFPo,743
39
+ ai_review/clients/github/pr/schema/comments.py,sha256=NrHsAhjrEv6WbApGfji4xKkCzQ8sMVfrEBoj_g1uTGs,1380
37
40
  ai_review/clients/github/pr/schema/files.py,sha256=ARirokToZ1zqMWh2jpDtVIs4qw5rlL7xfoRDJBJF71o,359
38
- ai_review/clients/github/pr/schema/pull_request.py,sha256=EwOworYQY4kCmL6QFKEXK7r2fpINK8o-4-FEy9-nTpg,688
41
+ ai_review/clients/github/pr/schema/pull_request.py,sha256=Fr41RCLhmAloEIfJQVj-hfLKmgo260tRQwbCkVN1cYw,694
39
42
  ai_review/clients/github/pr/schema/reviews.py,sha256=qRJpBu03CBwC_tPng9q9tkqT_u2WcdDELblAi-OzxWI,380
43
+ ai_review/clients/github/pr/schema/user.py,sha256=odOgadMfNck4M53BZ49vKJjWMqKFoqvnGwGuFVgT2Yw,109
40
44
  ai_review/clients/gitlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
45
  ai_review/clients/gitlab/client.py,sha256=MIZed-V4JUzntkU9vJq7Fkp5VAjnzjvep_5QM5ni_Co,1151
42
46
  ai_review/clients/gitlab/tools.py,sha256=ed8t2-dy2XtSRpYWhLxUobYvbBX_1zMZTPuzjbgPzTg,136
43
47
  ai_review/clients/gitlab/mr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- ai_review/clients/gitlab/mr/client.py,sha256=39EjS0bvvi8-kiBOkBa7N1q0wHb0qTgo_KvQise61js,6350
45
- ai_review/clients/gitlab/mr/types.py,sha256=tZ3rDDkzJM8v4zPt4gTyKCL30htiPQE9F_kVR6K5JHA,1280
48
+ ai_review/clients/gitlab/mr/client.py,sha256=ydkecV9SlmXJvkoBVF0c-5C7RsadYTP9RXC7tKLjJWo,7611
49
+ ai_review/clients/gitlab/mr/types.py,sha256=3PpUjnek6AOAiIC0tYRuX4RwB2UeoIrSxigTvsGC1iI,1563
46
50
  ai_review/clients/gitlab/mr/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- ai_review/clients/gitlab/mr/schema/changes.py,sha256=ZqSPb8zO0z_V8cEjxoTqnwbjRLxo6OTV4LeQEAg91cU,835
48
- ai_review/clients/gitlab/mr/schema/discussions.py,sha256=owaWWD5lMG9GXkT8kgHiU_-khYTWGHanbWgSKDiJknA,814
49
- ai_review/clients/gitlab/mr/schema/notes.py,sha256=DX9juurMYKcaYobh4n4M49dvHtUiLw5IzZKsGdBMxZg,448
51
+ ai_review/clients/gitlab/mr/schema/changes.py,sha256=qYvAih3zSvNuF4C8PtnuwmZVFk8VHM14miPxgC8hWG4,824
52
+ ai_review/clients/gitlab/mr/schema/discussions.py,sha256=mbVc-n39MjJcWsSHQCFsLTJuvDZb3QrM-CjWYBNf8us,1083
53
+ ai_review/clients/gitlab/mr/schema/notes.py,sha256=Z0NxDbgEo9CpKZbBjJNpoEuv8Q_u0oiH5GAjBeS2KMo,561
54
+ ai_review/clients/gitlab/mr/schema/user.py,sha256=RxgCM8oryPBNPDaFxcVqe11MogchMGaO1gALkZiscrU,112
50
55
  ai_review/clients/ollama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
56
  ai_review/clients/ollama/client.py,sha256=KoJ9J5_Vfpv5XNJREshE_gA46uo9J0Z3qVC7wJPEcX8,1720
52
57
  ai_review/clients/ollama/schema.py,sha256=A6oKwkkEVrduyzMR_lhLnaLyvKXqlfsXjkMIF2eXaYw,1310
@@ -67,8 +72,8 @@ ai_review/libs/config/base.py,sha256=sPf3OKeF1ID0ouOwiVaUtvpWuZXJXQvIw5kbnPUyN9o
67
72
  ai_review/libs/config/core.py,sha256=ZQ2QtYr7vAF0tXbVLvVwk9QFE5h6JjAKAUQWcb9gHws,87
68
73
  ai_review/libs/config/http.py,sha256=dx5PwgnGbPocUwf9QRhFmXmjfFDoeerOM04yB3B6S8w,398
69
74
  ai_review/libs/config/logger.py,sha256=oPmjpjf6EZwW7CgOjT8mOQdGnT98CLwXepiGB_ajZvU,384
70
- ai_review/libs/config/prompt.py,sha256=8aO5WNnhVhQcpWzWxqzb9lq6PzormaJazVwPHuf_ia8,4469
71
- ai_review/libs/config/review.py,sha256=LEZni68iH_0m4URPfN0d3F6yrrK7KSn-BwXf-7w2al8,1058
75
+ ai_review/libs/config/prompt.py,sha256=jPBYvi75u6BUIHOZnXCg5CiL0XRONDfW5T4WaYlxPEE,6066
76
+ ai_review/libs/config/review.py,sha256=q2EwLvUzsOp_WW1gtd_8fvUhAoStWiNGicxOYP4gm9E,1198
72
77
  ai_review/libs/config/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
78
  ai_review/libs/config/llm/base.py,sha256=ovvULFhfwH66_705D1O87ZGMeaQOZO7ZQhRUzzfzguU,2089
74
79
  ai_review/libs/config/llm/claude.py,sha256=MoalXkBA6pEp01znS8ohTRopfea9RUcqhZX5lOIuek8,293
@@ -98,20 +103,26 @@ ai_review/libs/http/event_hooks/base.py,sha256=cnSOOButTJYKeyb_OnGms1vXRfwfExP81
98
103
  ai_review/libs/http/event_hooks/logger.py,sha256=8_omfl6q3JijaBBIgzvzb4SayjNEDW-oxyck_Ky8wnI,603
99
104
  ai_review/libs/http/transports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
105
  ai_review/libs/http/transports/retry.py,sha256=S66-SKvJvIgqBknDgEnqciTB0g2-ZQ7JubQtkzv8P44,1772
106
+ ai_review/libs/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
+ ai_review/libs/llm/output_json_parser.py,sha256=JYSRJMAFp_Hy9on33dmVif8qJ66iSo8KObSIq6cx47M,2189
101
108
  ai_review/libs/template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
109
  ai_review/libs/template/render.py,sha256=PwLG46fXg8P3gZvmJB93P51G2IBdsEK2I8oDlLGmA-4,414
103
110
  ai_review/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
111
  ai_review/prompts/default_context.md,sha256=W8LvCMQxaX09NhPokwuxYLlA1jPCYor80GgZO8nhKbc,633
105
112
  ai_review/prompts/default_inline.md,sha256=UlxozaY5NtdZvA_d3qtAwIQSLP3C5JJh-mJtxGp_u0Q,257
113
+ ai_review/prompts/default_inline_reply.md,sha256=gG4ze6DJanpjvKWH0jzlg_H5IoYUQpLGIOji6YoOXBM,509
106
114
  ai_review/prompts/default_summary.md,sha256=jfO7hd-aHUbYvWFJwosbPwEYINRaM_W30pqOT_YNOco,182
115
+ ai_review/prompts/default_summary_reply.md,sha256=TiJ9WGvrmiYWFcjUK6dQJxWC819aRUFeohOd44BqWiU,756
107
116
  ai_review/prompts/default_system_context.md,sha256=HLTCkiZBuW-LsT5VqIs56mhKg48R1Xu67FbptliOTpQ,1002
108
117
  ai_review/prompts/default_system_inline.md,sha256=l8Hf82Jo7urELpKiPhDusdU9ag5eCWKn55_62Y0fmSY,826
118
+ ai_review/prompts/default_system_inline_reply.md,sha256=OhWQ5PZ-QFFgVVfmrsXEmvNAXDl9mTBll7zU-q1Mu6U,1011
109
119
  ai_review/prompts/default_system_summary.md,sha256=unEJ09G925TKqvjkTFKgl3g2AXT9GICe8kxTO50QhRg,224
120
+ ai_review/prompts/default_system_summary_reply.md,sha256=qGc_qQtVUpmj_gOw-6dhL2gz6saSA__9UOcS0jAjBD0,687
110
121
  ai_review/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
122
  ai_review/resources/pricing.yaml,sha256=jZHCGF78GTlZsXC_IGZT8JutKqpUyKikYXwtxIFEAaE,746
112
123
  ai_review/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
124
  ai_review/services/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
- ai_review/services/artifacts/schema.py,sha256=AD3cqw_NfPhcourFX-bayjbwNAaVyhq4T_p59lPEhMg,262
125
+ ai_review/services/artifacts/schema.py,sha256=o4dqG5LFCdAQY3wjRF5rImANe-X20g4zX_bCIKiHLSk,291
115
126
  ai_review/services/artifacts/service.py,sha256=SDHwYm9I4pSPISyNWqHEOR-wTTEa5ThsIi458C9hBt8,1789
116
127
  ai_review/services/artifacts/tools.py,sha256=_ZVNwyhZDiGlPAtIgLzb7TF1zBGJy8Hq32H3xoGvOkQ,223
117
128
  ai_review/services/artifacts/types.py,sha256=VPEDuQQciyQL8qcmgFuZxZUuuh2-xLwqwxmNZr62F3E,448
@@ -129,9 +140,9 @@ ai_review/services/git/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
129
140
  ai_review/services/git/service.py,sha256=_RMwgcllDoSLUzl84JML38fWkr7swnkUr6MJ46hSkWw,1282
130
141
  ai_review/services/git/types.py,sha256=QTOCTmR-Rt3sUjzZQHu2PGo_6un5gvNupifAa84wON4,413
131
142
  ai_review/services/hook/__init__.py,sha256=HDukG_ZosgGg4dT5GCGIzqZX7llbyYUofKVFeG7YR2A,98
132
- ai_review/services/hook/constants.py,sha256=uQJld5tJVUFk506h5RswTqLy-sIYxQfuQcUwflt7uas,875
133
- ai_review/services/hook/service.py,sha256=InPoWBas6SPoy0KUyKJFg5xVk90jBlWdWtUTaX71G88,6364
134
- ai_review/services/hook/types.py,sha256=zwOmnZVGlg53vUoC2rHNhpEiNsTpf0Tnb-s3SRPKFys,1405
143
+ ai_review/services/hook/constants.py,sha256=GthpBviiqcb3Oj5uhiJhyYGmWuwKgLlToC8pyj8klRM,1585
144
+ ai_review/services/hook/service.py,sha256=00qai06eFqkeKtIfqxlJkWTLCpO5d2wZzc2rFsPLKTs,10680
145
+ ai_review/services/hook/types.py,sha256=RrGFCPwRkOOLAoHpGlkcnT6Cao0B4PyPMN-Wxj6N9Uo,2461
135
146
  ai_review/services/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
147
  ai_review/services/llm/factory.py,sha256=AszDqufYPaZdVVR99UZBEFvnGdOildBFQ9uVOiBI1Tc,876
137
148
  ai_review/services/llm/types.py,sha256=OvbJWYRDThBgLhn9TWU0mliuanOW01CS3e8ermtuS-s,353
@@ -144,57 +155,98 @@ ai_review/services/llm/ollama/client.py,sha256=817nOQRsnaVqoY6LdO95l5JkRHkGvvS8T
144
155
  ai_review/services/llm/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
156
  ai_review/services/llm/openai/client.py,sha256=c3DWwLnwTheERdSGnMiQIbg5SaICouUAGClcQZSh1fE,1159
146
157
  ai_review/services/prompt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
- ai_review/services/prompt/adapter.py,sha256=YgD8Cf73pwPOnKxq9QSlbYr8wySfDxJE_3fIrRWfkUo,984
158
+ ai_review/services/prompt/adapter.py,sha256=9ntRxG5iON2vU54k8-BmLpiPCH5jRv2GGl01nmHj-SI,988
148
159
  ai_review/services/prompt/schema.py,sha256=ttla_lkvBQ-jfaZXzWSAAUrJROYRsozHHd5IoZc59zA,1324
149
- ai_review/services/prompt/service.py,sha256=58OJ6nIPSgXQyAqUXkWAXYAbNz7vMRemtllvD7bvQv0,2218
150
- ai_review/services/prompt/tools.py,sha256=-gS74mVM3OZPKWQkY9_QfStkfxaUfssDbJ3Bdi4AQ74,636
151
- ai_review/services/prompt/types.py,sha256=uVcvW8ZuwmM02MjCmw6Rg-IW5pIT3MeEYl0Vl-jzV4M,913
160
+ ai_review/services/prompt/service.py,sha256=AvhLMfwmIxbnPWdViSSclwUUqnHGx2V-hSMszCC9EQ4,3723
161
+ ai_review/services/prompt/tools.py,sha256=7yKQmHajlwFE37tvmMbbBYDmFObFVOb1ubHhNXBdAnE,1229
162
+ ai_review/services/prompt/types.py,sha256=9p1RHuR5-5DNV0AtR_VtiT5OHo6eNqKzGggQoPWiSh8,1572
152
163
  ai_review/services/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
- ai_review/services/review/service.py,sha256=tDeYHet2hNOn057VSYJVENbRrGLVfHtlf1q3Cv5VbSo,6947
164
+ ai_review/services/review/service.py,sha256=oqRJfWcww-ZuW5BToXqEymLCLlQbRSZ1ng5LxpUG_Y8,5286
154
165
  ai_review/services/review/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
- ai_review/services/review/gateway/comment.py,sha256=QbswfdDDOWEhC1K6IQ4plPzgeqEX4X9JQe1NcZVazk0,2794
156
- ai_review/services/review/gateway/llm.py,sha256=kThcCJdWxsFARWA5bxcZx6EOl54dh2UGknNh-f6Sl_M,1431
157
- ai_review/services/review/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
- ai_review/services/review/inline/schema.py,sha256=JYhuDiA3xxr3ItSAiJdaEy8loFVNiJEsZGZlFaNNhoU,1504
159
- ai_review/services/review/inline/service.py,sha256=EdNz-VwoRwrj-HDYqVIZIHq0nEK7SqWtt7z_VHHVVV0,2245
160
- ai_review/services/review/inline/types.py,sha256=NF5GNcpYkvYnXITv2FWGhrirkwpKjcp1TooDpJ1gXec,334
161
- ai_review/services/review/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
- ai_review/services/review/policy/service.py,sha256=yGDePLxAEF3N1Pkh47jGVd-4dGEESyxDXIXxV7KQfuY,2027
163
- ai_review/services/review/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
- ai_review/services/review/summary/schema.py,sha256=GipVNWrEKtgZPkytNSrXwzvX9Zq8Pv2wxjXhfJq4D3g,364
165
- ai_review/services/review/summary/service.py,sha256=F4diIESc0y7YSiUKbInHWiSOW5tW_eQ0rpf78wKxLAo,562
166
- ai_review/services/review/summary/types.py,sha256=iDsucvx9xJZ5Xb5FN70da3bub3YDtt4vpQeVEK532E8,235
166
+ ai_review/services/review/gateway/comment.py,sha256=gOFoEFXIJ9SX7B05dTO605dUOnrchCtB-a2ExXCfUxE,5019
167
+ ai_review/services/review/gateway/llm.py,sha256=5BQU8Vmo55pzWkVk6s_w5B3qX4tSkjjtj7wWWhLyc9s,1534
168
+ ai_review/services/review/gateway/types.py,sha256=C9zOUF0ZDnSa568T3AIWIxpNdnpcB8QUxU1rVqx7lZc,1795
169
+ ai_review/services/review/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
170
+ ai_review/services/review/internal/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
+ ai_review/services/review/internal/inline/schema.py,sha256=JYhuDiA3xxr3ItSAiJdaEy8loFVNiJEsZGZlFaNNhoU,1504
172
+ ai_review/services/review/internal/inline/service.py,sha256=BBY5l_b53gdfFvyw-3GkIePUuVLGjaDOABUj8FTikeE,1614
173
+ ai_review/services/review/internal/inline/types.py,sha256=QCy0YjfKObjJjkZd3vG9-v9Hj8ibOUc92mJIAZGFxRA,248
174
+ ai_review/services/review/internal/inline_reply/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
+ ai_review/services/review/internal/inline_reply/schema.py,sha256=p0BZLoMcGhWxqKRJyW_f52KK9KujgbKOitjbi8x3xcU,621
176
+ ai_review/services/review/internal/inline_reply/service.py,sha256=1Rnn-9_kcBOaOHGrVGi9ffCbKl04oeA49U3Ja3BtX1A,925
177
+ ai_review/services/review/internal/inline_reply/types.py,sha256=7Sddi_k4WEypGBwP3m-UZ2dISyHEP-QNjevL6c3H3Vg,268
178
+ ai_review/services/review/internal/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
+ ai_review/services/review/internal/policy/service.py,sha256=CiVY74OpuVtnXO6B4Cnr5BLxwNL2IrPfAKAbkTvLVhk,2144
180
+ ai_review/services/review/internal/policy/types.py,sha256=28KfCMAjXqQ_oewLIcGL3poYsE5HQB_ezQMzzPKSgPU,372
181
+ ai_review/services/review/internal/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
+ ai_review/services/review/internal/summary/schema.py,sha256=GipVNWrEKtgZPkytNSrXwzvX9Zq8Pv2wxjXhfJq4D3g,364
183
+ ai_review/services/review/internal/summary/service.py,sha256=7mWB5uELXWsWehQG3oNVBi-fUzNwLFMpKJntltICOnM,580
184
+ ai_review/services/review/internal/summary/types.py,sha256=6rq3bvERtf_JAMHNg6PYEfTq9Rge8vTQwfDrtUzb_Z8,244
185
+ ai_review/services/review/internal/summary_reply/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
+ ai_review/services/review/internal/summary_reply/schema.py,sha256=DRFh8eJHW4Q--XDKX9Iup7VksRPGVsF6zQS7MEB7ZPo,290
187
+ ai_review/services/review/internal/summary_reply/service.py,sha256=sM3s2KaVr7mdN33OGwe5KnGdPlQOdVheu3mvrQ9drR0,628
188
+ ai_review/services/review/internal/summary_reply/types.py,sha256=sqZzybdHK7TeUvlpuUm2H314_59_WzGzgbV3KAWCm-8,265
189
+ ai_review/services/review/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
+ ai_review/services/review/runner/context.py,sha256=dbGSpVqCNOu9s2d8g0Mxhw3n8nqhu2DPAW6Hl-zVhjY,3302
191
+ ai_review/services/review/runner/inline.py,sha256=j5IbowJmydXcg_zMCE-fveDz7uUuaUiLtP51-qNRtXo,3684
192
+ ai_review/services/review/runner/inline_reply.py,sha256=-5OEss2X1MmwRWKCrCGUSLHDVl0dCV5NYsGukMPbGx4,3717
193
+ ai_review/services/review/runner/summary.py,sha256=KfQkfw_sqyvKnsi2-eD2YLfjfpOMaVjo6-gYW9RHnAo,3215
194
+ ai_review/services/review/runner/summary_reply.py,sha256=8YWMhw4dNjFgxTTgxyb6yLh-CkK_4AtfP36eD0DV4nY,3683
195
+ ai_review/services/review/runner/types.py,sha256=lZJCiCAHnedXqYBIvnb8A0HzOQd3GEPWC_wu_mk46KY,113
167
196
  ai_review/services/vcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
197
  ai_review/services/vcs/factory.py,sha256=AfhpZjQ257BkLjb_7zUyw_EUnfEiCUHgTph7GGm-MY4,753
169
- ai_review/services/vcs/types.py,sha256=S49LhAGHVAd_0QwZUr4JMhfc6DR-HikHR6-T_ETlTus,1998
198
+ ai_review/services/vcs/types.py,sha256=LemhQ4LAGlOdwMSF-HlYIo7taSRu4494YQ0Rp2PBgcg,3169
170
199
  ai_review/services/vcs/bitbucket/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
- ai_review/services/vcs/bitbucket/client.py,sha256=OceM48MBoiUVKGTh8ZrrpVt8a1fDczCvOMD9VlwoapY,7253
200
+ ai_review/services/vcs/bitbucket/adapter.py,sha256=kWR7QXeg9GXnGyMpn_v-2roVRRFEAvGiKF8R-xXgczI,871
201
+ ai_review/services/vcs/bitbucket/client.py,sha256=dhsgJ3uYzWEwEX1XEi_TTQkfCc5xAc9B_c1F9hwPR7M,10401
172
202
  ai_review/services/vcs/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- ai_review/services/vcs/github/client.py,sha256=v6NV97xi_rtRQQi8atRdSrXKhSOQ7CeRHK7YjoyjU6Q,6353
203
+ ai_review/services/vcs/github/adapter.py,sha256=pxcbSLEXkOg1c1NtzB0hkZJVvyC4An9pCzNK5sPJKbA,1212
204
+ ai_review/services/vcs/github/client.py,sha256=rSVvpyovT1wDLq0fIQPe5UJqmgIgIFh2P-CPqIQ_sf0,9371
174
205
  ai_review/services/vcs/gitlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
- ai_review/services/vcs/gitlab/client.py,sha256=LK95m-uFSxhDEVU-cBGct61NTKjul-ieLZPxfBLIPts,6730
206
+ ai_review/services/vcs/gitlab/adapter.py,sha256=RkBalrgY8EyxIB8QSH4r4PoTDhg46GROHh2zQyQ4zuY,999
207
+ ai_review/services/vcs/gitlab/client.py,sha256=vPiIpTFEnLXkUV4tSqRJPab13kkLNlUfrIticzmTRGQ,9498
176
208
  ai_review/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
209
  ai_review/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
210
  ai_review/tests/fixtures/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
- ai_review/tests/fixtures/clients/bitbucket.py,sha256=XJK1nU7Wir5PnmwCUJ_2uTlByA5a_CTEuXc2a-WmWio,7122
211
+ ai_review/tests/fixtures/clients/bitbucket.py,sha256=K4Ez_hTOVKz5-KlXbgTOVDec6iewxkm8hqDJvebhnpE,7124
180
212
  ai_review/tests/fixtures/clients/claude.py,sha256=6ldJlSSea0zsZV0hRDMi9mqWm0hWT3mp_ROwG_sVU1c,2203
181
213
  ai_review/tests/fixtures/clients/gemini.py,sha256=zhLJhm49keKEBCPOf_pLu8_zCatsKKAWM4-gXOhaXeM,2429
182
- ai_review/tests/fixtures/clients/github.py,sha256=Mzr8LcvVlYLhimzDMG4tEOQwj_6E6kTvYvSrq04R3YI,6865
183
- ai_review/tests/fixtures/clients/gitlab.py,sha256=_0JSN-ixA7nDOwY18BlL_L9fh_qmT1_6sxGx_CIRhmM,5540
214
+ ai_review/tests/fixtures/clients/github.py,sha256=kC1L-nWZMn9O_uRfuT_B8R4sn8FRvISlBJMkRKaioS0,7814
215
+ ai_review/tests/fixtures/clients/gitlab.py,sha256=9jVvo5b_-SULDAh7Kij7ueZqraqBZgBig0HuDzn8_tg,6921
184
216
  ai_review/tests/fixtures/clients/ollama.py,sha256=UUHDDPUraQAG8gBC-0UvftaK0BDYir5cJDlRKJymSQg,2109
185
217
  ai_review/tests/fixtures/clients/openai.py,sha256=UgfuRZWzl3X7ZVHMLKP4mZxNXVpcccitkc9tuUyffXE,2267
218
+ ai_review/tests/fixtures/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
+ ai_review/tests/fixtures/libs/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
+ ai_review/tests/fixtures/libs/llm/output_json_parser.py,sha256=Eu0tCK5cD1d9X1829ruahih7jQoehGozIEugS71AAA8,275
186
221
  ai_review/tests/fixtures/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
222
  ai_review/tests/fixtures/services/artifacts.py,sha256=V5FvUnC9OAo0n-paxxJP5OxAgLz1Zz3OZ8zZvqu_01w,1462
188
223
  ai_review/tests/fixtures/services/cost.py,sha256=A6Ja0CtQ-k6pR2-B5LRE8EzkqPL34xHGXYtaILjhYvw,1612
189
224
  ai_review/tests/fixtures/services/diff.py,sha256=rOLFR-giYJlE2qUYTOT9BxyJhQ-fbXDdYCw3zed4-9M,1471
190
225
  ai_review/tests/fixtures/services/git.py,sha256=zDNNLZDoVC7r4LuF1N1MUgzhcAl2nhDdFC9olpR_PjQ,1441
191
- ai_review/tests/fixtures/services/llm.py,sha256=Wztlk0C2va_2z378dPwKoaQKFHSh5k7HWJkn-LY-k-8,886
192
- ai_review/tests/fixtures/services/prompt.py,sha256=dk0zretwVGTc0Pzt73zKf8Q36Vo7F_3s4O5NfTjfVqE,1920
193
- ai_review/tests/fixtures/services/vcs.py,sha256=Nz76T82DT7V0nVBWrchTKKHAy27KJKQGToNHfpG_bTM,1751
226
+ ai_review/tests/fixtures/services/hook.py,sha256=1QeOwHJn_mwTABbYDeNzCx9t6mn5Ao4guptVFSG-LlI,141
227
+ ai_review/tests/fixtures/services/llm.py,sha256=Wwt0pGM3Soq4H_yjTDzYHXhb75F2-MKe2cwj94ya9AE,826
228
+ ai_review/tests/fixtures/services/prompt.py,sha256=ymE1G7Hzo8W-0AmaGZaBtn6boSJm3CwGWj5afjYTXgI,5178
229
+ ai_review/tests/fixtures/services/vcs.py,sha256=RXfbuW0Ffx7km7q2Zck__1qTZdZ-_vNr9utC8Kokap4,2810
194
230
  ai_review/tests/fixtures/services/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
- ai_review/tests/fixtures/services/review/inline.py,sha256=k4IW6oy5JHMo9Kv0H97DLlFyrGsEInaozObjLARzdPg,1041
196
- ai_review/tests/fixtures/services/review/summary.py,sha256=Hkt8mq1ZmqMH5_mELrS1x0wtCoNPbBjOEQ9yIsMbRts,691
231
+ ai_review/tests/fixtures/services/review/base.py,sha256=10LaT6xi5IP0CrR6LfatirVKnZ7D0n8Q1dV99nOBEuE,1501
232
+ ai_review/tests/fixtures/services/review/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
233
+ ai_review/tests/fixtures/services/review/gateway/comment.py,sha256=nm_dA3teFK5cZJltKS9UcDlUvxmbClii56CCv4vkRF8,4063
234
+ ai_review/tests/fixtures/services/review/gateway/llm.py,sha256=OXYZtJbQ8VqvNlPxG6CLPT0mz-HrhfZA8hoEAgf8loM,515
235
+ ai_review/tests/fixtures/services/review/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
236
+ ai_review/tests/fixtures/services/review/internal/inline.py,sha256=D-npuBMSsP_ng5RgplaUZnANl3q5f7GD4OkE8IvQv2M,1038
237
+ ai_review/tests/fixtures/services/review/internal/inline_reply.py,sha256=NRfcVBHavyHvoxOiqMhYhcf6YWDLfT367ZoXeUZIieU,1047
238
+ ai_review/tests/fixtures/services/review/internal/policy.py,sha256=q9Trrby5ddDrAkt5a-O-lbA_a0qV8hnA6ofNZh_4VGE,1090
239
+ ai_review/tests/fixtures/services/review/internal/summary.py,sha256=dHKvw2BsfOf4Qe1ONpjmiEJ5bgyiNbBFmyXZ0bEbDKo,809
240
+ ai_review/tests/fixtures/services/review/internal/summary_reply.py,sha256=y8uT2bbcxJo1SXq9obJ71VkIhnKRQV7pdDzWhkxqGIg,827
241
+ ai_review/tests/fixtures/services/review/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
242
+ ai_review/tests/fixtures/services/review/runner/context.py,sha256=3FJ-rOyjiWMTtSfu8eAdVOKo_5uZXHe5RD7bkGVljMk,2023
243
+ ai_review/tests/fixtures/services/review/runner/inline.py,sha256=aaHdl6_YtEmS1H2IMIany5Ee0wQFeJ51DNmg-KwA6qQ,2014
244
+ ai_review/tests/fixtures/services/review/runner/inline_reply.py,sha256=3t04gieUpOU8WN1hgh_oETS1LQLxQ4nbhWVkN6g1CSY,2096
245
+ ai_review/tests/fixtures/services/review/runner/summary.py,sha256=okcT4HCkpu6Mu2XQZQhnWTPHdZeUeWdQFz9XhJNGGpw,2029
246
+ ai_review/tests/fixtures/services/review/runner/summary_reply.py,sha256=-ki34QgmDjN7CE-ViS5tCGfgBNpjN2PQUbe13euY3JE,2111
197
247
  ai_review/tests/suites/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
+ ai_review/tests/suites/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
+ ai_review/tests/suites/cli/test_main.py,sha256=_h2wvZAryfhearOJbbBA8bbAhiYwjY88qk3qyTA4JCk,2218
198
250
  ai_review/tests/suites/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
199
251
  ai_review/tests/suites/clients/bitbucket/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
252
  ai_review/tests/suites/clients/bitbucket/test_client.py,sha256=1qEkznC01hkh6TPpzChY9glhK6OTX-pfnSF43KNBtrY,600
@@ -222,13 +274,15 @@ ai_review/tests/suites/libs/test_json.py,sha256=q_tvFcL9EaN5jr48Ed_mxMEmW6xXS0xl
222
274
  ai_review/tests/suites/libs/asynchronous/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
275
  ai_review/tests/suites/libs/asynchronous/test_gather.py,sha256=Uzo0ctGFlllJU6TqA6hVWu_mcycJBAX5am8_bDO2eXk,1282
224
276
  ai_review/tests/suites/libs/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
225
- ai_review/tests/suites/libs/config/test_prompt.py,sha256=kDMTnykC54tTPfE6cqYRBbV8d5jzAKucXdJfwtqUybM,2242
277
+ ai_review/tests/suites/libs/config/test_prompt.py,sha256=H3QC6LvYAwebnLed-NeT86TY9kPaMPy7Eppk5Bfi2SM,5601
226
278
  ai_review/tests/suites/libs/diff/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
279
  ai_review/tests/suites/libs/diff/test_models.py,sha256=RBFQ97LWhU8TlupxXkJ97ryAvJrSuOHLtT9biUBUMXg,3321
228
280
  ai_review/tests/suites/libs/diff/test_parser.py,sha256=rvWEVGIdaLBlDAnSevjRY7I1Zikj12d5GOgMk9QyHQQ,3013
229
281
  ai_review/tests/suites/libs/diff/test_tools.py,sha256=XkHJZ-b5veFz5oLKO09P7npaLN8lOzCnGR7e83Zv_mg,1953
230
282
  ai_review/tests/suites/libs/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
231
283
  ai_review/tests/suites/libs/http/test_paginate.py,sha256=9PCn1mUQypPId9l8RToBQnLBJBV_WEYxBh785bqqmMA,2694
284
+ ai_review/tests/suites/libs/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
+ ai_review/tests/suites/libs/llm/test_output_json_parser.py,sha256=2KwnXZc3dlUWM1IFS5PJpB9zpDKPiX7c-vRiHl_rPVU,5721
232
286
  ai_review/tests/suites/libs/template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
233
287
  ai_review/tests/suites/libs/template/test_render.py,sha256=n-ss5bd_hwc-RzYmqWmFM6KSlP1zLSnlsW1Yki12Bpw,1890
234
288
  ai_review/tests/suites/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -240,7 +294,7 @@ ai_review/tests/suites/services/diff/test_renderers.py,sha256=IKOpsGedONNW8ZfYTA
240
294
  ai_review/tests/suites/services/diff/test_service.py,sha256=evFe1I-ulOYdkhQS9NC8Bol4jXuhEnb2iArTAzckWrA,3195
241
295
  ai_review/tests/suites/services/diff/test_tools.py,sha256=vsOSSIDZKkuD8dMCoBBEBt7WcYTNgxxCR6YNv2HEqqk,3624
242
296
  ai_review/tests/suites/services/hook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
243
- ai_review/tests/suites/services/hook/test_service.py,sha256=GM_AiNVGP2Pgp-3BwGOAIfA8lLXl6ah28ey77KZz_C4,2750
297
+ ai_review/tests/suites/services/hook/test_service.py,sha256=TjNU2xiOQfUZZa8M3L2eHbtTwxse_B7QNn2h4118z1U,6637
244
298
  ai_review/tests/suites/services/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
299
  ai_review/tests/suites/services/llm/test_factory.py,sha256=Lp37aXM08fHaLzgwRBw5xZEDZkPDNhJ4qwjtEwGENv8,1394
246
300
  ai_review/tests/suites/services/llm/claude/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -252,31 +306,50 @@ ai_review/tests/suites/services/llm/ollama/test_client.py,sha256=Eu4OERB00SJwCKz
252
306
  ai_review/tests/suites/services/llm/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
253
307
  ai_review/tests/suites/services/llm/openai/test_client.py,sha256=yzIL8GYHyX9iLKIlaF__87aue9w0cr66feoMaCv5gms,761
254
308
  ai_review/tests/suites/services/prompt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
255
- ai_review/tests/suites/services/prompt/test_adapter.py,sha256=9KZOFQmZUs3l_cW7Q5LIMPs4i4J-gOCQ6VrlDPR0ImU,2156
309
+ ai_review/tests/suites/services/prompt/test_adapter.py,sha256=3BhaGW4G-72dN_ajp5rJst39k1VNiKZq5FUB9LGPNVQ,2168
256
310
  ai_review/tests/suites/services/prompt/test_schema.py,sha256=rm2__LA2_4qQwSmNAZ_Wnpy11T3yYRkYUkRUrqxUQKE,5421
257
- ai_review/tests/suites/services/prompt/test_service.py,sha256=WXYKwDHMmWD6ew1awiEzmoxEJtQBqxvOgiyK8Ii9Mhw,6755
258
- ai_review/tests/suites/services/prompt/test_tools.py,sha256=_yNZoBATvPU5enWNIopbjY8lVVjfaB_46kNIKODhCW4,1981
311
+ ai_review/tests/suites/services/prompt/test_service.py,sha256=jfpmM--eZH43NylwltX-ijmF58ZJ4WA83kmGshUbJfs,8312
312
+ ai_review/tests/suites/services/prompt/test_tools.py,sha256=SmweFvrpxd-3RO5v18vCl7zonEqFE1n4eqHH7-6auYM,4511
259
313
  ai_review/tests/suites/services/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
- ai_review/tests/suites/services/review/test_service.py,sha256=fCmTSb8bDPjvbORGpStz4YqqWqXBnvIQy_soJXPa1wQ,5690
261
- ai_review/tests/suites/services/review/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
- ai_review/tests/suites/services/review/inline/test_schema.py,sha256=C5H6zqEHaf9OO4VHX0atYAt21CmOcCARaijSo-FUqj8,2368
263
- ai_review/tests/suites/services/review/inline/test_service.py,sha256=x8d-dhw_uEXtGVLDVv4xVodmscrXIfDkoAnG4UapdlQ,3815
264
- ai_review/tests/suites/services/review/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
265
- ai_review/tests/suites/services/review/policy/test_service.py,sha256=kRWT550OjWYQ7ZfsihBRc-tx-NMkhlynEsqur55RK0M,3687
266
- ai_review/tests/suites/services/review/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
267
- ai_review/tests/suites/services/review/summary/test_schema.py,sha256=HUbSDbQzBp-iTsGLs7hJfu-sz6sq9xLO0woGmZPWyx0,735
268
- ai_review/tests/suites/services/review/summary/test_service.py,sha256=ibiYOWQMZuQKRutIT_EKGq7DEPQvp62YhscNHeSWFVQ,588
314
+ ai_review/tests/suites/services/review/test_service.py,sha256=1KSgYQ1SfO4dserZTMrkLfAzv0466k7LQG8m4TA_rGk,3324
315
+ ai_review/tests/suites/services/review/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
+ ai_review/tests/suites/services/review/gateway/test_comment.py,sha256=mFraqWLAF2yTcy8qAwAE5YjuWsab7GixFT5II3Ca7zg,8816
317
+ ai_review/tests/suites/services/review/gateway/test_llm.py,sha256=WO326PiZkF4fHPYl1CRDfpUkLsC2BrLPmJpu0rnWrwY,2903
318
+ ai_review/tests/suites/services/review/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
319
+ ai_review/tests/suites/services/review/internal/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
320
+ ai_review/tests/suites/services/review/internal/inline/test_schema.py,sha256=2SGF8yNHsNv8lwG-MUlgO3RT4juTt0PQSl10qNhSt7o,2377
321
+ ai_review/tests/suites/services/review/internal/inline/test_service.py,sha256=SZ-RDJaZwirU5wm5ikSCbVg_jn62ydUIoyorIxXkEmI,3357
322
+ ai_review/tests/suites/services/review/internal/inline_reply/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
+ ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py,sha256=YteWEDnXsUYMKVBPH2xejwUDmIlASSZTIml3PYIsk6Q,2075
324
+ ai_review/tests/suites/services/review/internal/inline_reply/test_service.py,sha256=AzfU7IFe71dJo2xjTvJq6fFuxXxap5QqcfkW_ObVbSg,3110
325
+ ai_review/tests/suites/services/review/internal/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
326
+ ai_review/tests/suites/services/review/internal/policy/test_service.py,sha256=iW6KYJ5CDypQT8TEXAlAmnjkVSGVS6tQ7wYrI3a2Dog,3696
327
+ ai_review/tests/suites/services/review/internal/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
328
+ ai_review/tests/suites/services/review/internal/summary/test_schema.py,sha256=lbav1_wbGh_emt8uPbffxjf54f4cQO1e2PRBUv-DqTo,744
329
+ ai_review/tests/suites/services/review/internal/summary/test_service.py,sha256=VbC5fZrvyAwgMon-pSFw6G_xKAoZIq7SW0HUBSeahRY,606
330
+ ai_review/tests/suites/services/review/internal/summary_reply/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
331
+ ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py,sha256=_2kfcHjB-thIFTIhdDBR7PsEl8beIAu4FtEkQjb0Ljk,859
332
+ ai_review/tests/suites/services/review/internal/summary_reply/test_service.py,sha256=VlVr9wXXwmpp9qxy_4dMZnFHSZ12j2QSP_m58Vs_wXE,709
333
+ ai_review/tests/suites/services/review/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
334
+ ai_review/tests/suites/services/review/runner/test_context.py,sha256=57RO3lBR35RfLizJ71wdvJ6MAVz9h8M8i7i6ZKF8MNY,3948
335
+ ai_review/tests/suites/services/review/runner/test_inline.py,sha256=ZehmjvoNe-0Zff55xBceBBg7tNn5AWRW_MdPNt-Uvrg,4651
336
+ ai_review/tests/suites/services/review/runner/test_inline_reply.py,sha256=X_vu1lB83z5k8VG7mfBZaCtfFkq2D4VnGpQEsNJOrmo,4888
337
+ ai_review/tests/suites/services/review/runner/test_summary.py,sha256=ePiORxLDtmsIqRA-eAZ8eDjVhVBjALrJ8jjIb6DlshE,3944
338
+ ai_review/tests/suites/services/review/runner/test_summary_reply.py,sha256=L-G_Jpf3etnNqgPp9fhCy3JH_gmniyl9IUPGyEvkRLM,4546
269
339
  ai_review/tests/suites/services/vcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
270
340
  ai_review/tests/suites/services/vcs/test_factory.py,sha256=EergKSHW4b7RZg9vJJ5Cj0XfPsDTLEclV1kq2_9greA,1138
271
341
  ai_review/tests/suites/services/vcs/bitbucket/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
272
- ai_review/tests/suites/services/vcs/bitbucket/test_service.py,sha256=JnG5BYTgGMb-doNjis2BOeI8JrMmvqwv82UFD5f92kg,4448
342
+ ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py,sha256=zOjAOxtSSN0le5_-3-vkucCnHZH0zIUer7ZAMUMo62A,3760
343
+ ai_review/tests/suites/services/vcs/bitbucket/test_client.py,sha256=oIlUdUBPgO2bfNyAsodUsAU7kRnETQVqmRJimRtEfBU,7846
273
344
  ai_review/tests/suites/services/vcs/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
274
- ai_review/tests/suites/services/vcs/github/test_service.py,sha256=c2sjecm4qzqYXuO9j6j35NQyJzqDpnXIJImRTcpkyHo,4378
345
+ ai_review/tests/suites/services/vcs/github/test_adapter.py,sha256=bK4k532v_8kDiud5RI9OlGetWMiLP8NaW1vEfHvcHfQ,4893
346
+ ai_review/tests/suites/services/vcs/github/test_client.py,sha256=mNt1bA6aVU3REsJiU_tK1PokQxQTaCKun0tNBHuvIp8,8039
275
347
  ai_review/tests/suites/services/vcs/gitlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
276
- ai_review/tests/suites/services/vcs/gitlab/test_service.py,sha256=0dqgL5whzjcP-AQ4adP_12QfkYm_ZtdtMotmYm8Se7Y,4449
277
- xai_review-0.27.0.dist-info/licenses/LICENSE,sha256=p-v8m7Kmz4KKc7PcvsGiGEmCw9AiSXY4_ylOPy_u--Y,11343
278
- xai_review-0.27.0.dist-info/METADATA,sha256=5SnK3Ip4vzfwvS110fYNDSDYD4OzrmA5G1eUV2oGMbE,11150
279
- xai_review-0.27.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
280
- xai_review-0.27.0.dist-info/entry_points.txt,sha256=JyC5URanMi5io5P_PXQf7H_I1OGIpk5cZQhaPQ0g4Zs,53
281
- xai_review-0.27.0.dist-info/top_level.txt,sha256=sTsZbfzLoqvRZKdKa-BcxWvjlHdrpbeJ6DrGY0EuR0E,10
282
- xai_review-0.27.0.dist-info/RECORD,,
348
+ ai_review/tests/suites/services/vcs/gitlab/test_adapter.py,sha256=VeORrVExX1rnrQluaBB7LUgmzl_FCwHgW-TAqG4qF1w,3368
349
+ ai_review/tests/suites/services/vcs/gitlab/test_client.py,sha256=8qvf0qGZSEa3fTpMMz6fL-JSFw1rQlPda9bjfKXDC7Y,8028
350
+ xai_review-0.28.0.dist-info/licenses/LICENSE,sha256=p-v8m7Kmz4KKc7PcvsGiGEmCw9AiSXY4_ylOPy_u--Y,11343
351
+ xai_review-0.28.0.dist-info/METADATA,sha256=3iCvsSWPGbG6VXl9xM8z7DAbDzACRS0uAf7C7PI5p6A,11358
352
+ xai_review-0.28.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
353
+ xai_review-0.28.0.dist-info/entry_points.txt,sha256=JyC5URanMi5io5P_PXQf7H_I1OGIpk5cZQhaPQ0g4Zs,53
354
+ xai_review-0.28.0.dist-info/top_level.txt,sha256=sTsZbfzLoqvRZKdKa-BcxWvjlHdrpbeJ6DrGY0EuR0E,10
355
+ xai_review-0.28.0.dist-info/RECORD,,
@@ -1,54 +0,0 @@
1
- import re
2
-
3
- from pydantic import ValidationError
4
-
5
- from ai_review.libs.json import sanitize_json_string
6
- from ai_review.libs.logger import get_logger
7
- from ai_review.services.review.inline.schema import InlineCommentListSchema
8
- from ai_review.services.review.inline.types import InlineCommentServiceProtocol
9
-
10
- logger = get_logger("INLINE_COMMENT_SERVICE")
11
-
12
- FIRST_JSON_ARRAY_RE = re.compile(r"\[[\s\S]*]", re.MULTILINE)
13
- CLEAN_JSON_BLOCK_RE = re.compile(r"```(?:json)?(.*?)```", re.DOTALL | re.IGNORECASE)
14
-
15
-
16
- class InlineCommentService(InlineCommentServiceProtocol):
17
- @classmethod
18
- def try_parse_model_output(cls, raw: str) -> InlineCommentListSchema | None:
19
- try:
20
- return InlineCommentListSchema.model_validate_json(raw)
21
- except ValidationError as error:
22
- logger.warning(f"Parse failed, trying sanitized JSON: {raw[:200]=}, {error=}")
23
- try:
24
- cleaned = sanitize_json_string(raw)
25
- return InlineCommentListSchema.model_validate_json(cleaned)
26
- except ValidationError as error:
27
- logger.warning(f"Sanitized JSON still invalid: {raw[:200]=}, {error=}")
28
- return None
29
-
30
- @classmethod
31
- def parse_model_output(cls, output: str) -> InlineCommentListSchema:
32
- output = (output or "").strip()
33
- if not output:
34
- logger.warning("️LLM returned empty string for inline review")
35
- return InlineCommentListSchema(root=[])
36
-
37
- if match := CLEAN_JSON_BLOCK_RE.search(output):
38
- output = match.group(1).strip()
39
-
40
- if parsed := cls.try_parse_model_output(output):
41
- return parsed
42
-
43
- logger.warning("Failed to parse LLM output as JSON, trying to extract first JSON array...")
44
-
45
- if json_array_match := FIRST_JSON_ARRAY_RE.search(output):
46
- if parsed := cls.try_parse_model_output(json_array_match.group(0)):
47
- logger.info("Successfully parsed JSON after extracting array from output")
48
- return parsed
49
- else:
50
- logger.error("Extracted JSON array is still invalid after sanitization")
51
- else:
52
- logger.error("No JSON array found in LLM output")
53
-
54
- return InlineCommentListSchema(root=[])
@@ -1,11 +0,0 @@
1
- from typing import Protocol
2
-
3
- from ai_review.services.review.inline.schema import InlineCommentListSchema
4
-
5
-
6
- class InlineCommentServiceProtocol(Protocol):
7
- def parse_model_output(self, output: str) -> InlineCommentListSchema:
8
- ...
9
-
10
- def try_parse_model_output(self, raw: str) -> InlineCommentListSchema | None:
11
- ...
@@ -1,19 +0,0 @@
1
- import pytest
2
-
3
- from ai_review.services.review.summary.schema import SummaryCommentSchema
4
- from ai_review.services.review.summary.types import SummaryCommentServiceProtocol
5
-
6
-
7
- class FakeSummaryCommentService(SummaryCommentServiceProtocol):
8
- def __init__(self, text: str = "This is a summary comment"):
9
- self.text = text
10
- self.calls: list[tuple[str, dict]] = []
11
-
12
- def parse_model_output(self, output: str) -> SummaryCommentSchema:
13
- self.calls.append(("parse_model_output", {"output": output}))
14
- return SummaryCommentSchema(text=self.text)
15
-
16
-
17
- @pytest.fixture
18
- def fake_summary_comment_service() -> FakeSummaryCommentService:
19
- return FakeSummaryCommentService()
@@ -1,107 +0,0 @@
1
- from ai_review.services.review.inline.schema import InlineCommentListSchema
2
- from ai_review.services.review.inline.service import InlineCommentService
3
-
4
-
5
- def test_empty_output_returns_empty_list():
6
- result = InlineCommentService.parse_model_output("")
7
- assert isinstance(result, InlineCommentListSchema)
8
- assert result.root == []
9
-
10
-
11
- def test_valid_json_array_parsed():
12
- json_output = '[{"file": "a.py", "line": 1, "message": "use f-string"}]'
13
- result = InlineCommentService.parse_model_output(json_output)
14
- assert len(result.root) == 1
15
- assert result.root[0].file == "a.py"
16
- assert result.root[0].line == 1
17
- assert result.root[0].message == "use f-string"
18
-
19
-
20
- def test_json_inside_code_block_parsed():
21
- output = """```json
22
- [
23
- {"file": "b.py", "line": 42, "message": "check for None"}
24
- ]
25
- ```"""
26
- result = InlineCommentService.parse_model_output(output)
27
- assert len(result.root) == 1
28
- assert result.root[0].file == "b.py"
29
- assert result.root[0].line == 42
30
-
31
-
32
- def test_non_json_but_array_inside_text():
33
- output = "some explanation...\n[ {\"file\": \"c.py\", \"line\": 7, \"message\": \"fix this\"} ]\nend"
34
- result = InlineCommentService.parse_model_output(output)
35
- assert len(result.root) == 1
36
- assert result.root[0].file == "c.py"
37
- assert result.root[0].line == 7
38
-
39
-
40
- def test_invalid_json_array_logs_and_returns_empty():
41
- output = '[{"file": "d.py", "line": "oops", "message": "bad"}]'
42
- result = InlineCommentService.parse_model_output(output)
43
- assert result.root == []
44
-
45
-
46
- def test_no_json_array_found_logs_and_returns_empty():
47
- output = "this is not json at all"
48
- result = InlineCommentService.parse_model_output(output)
49
- assert result.root == []
50
-
51
-
52
- def test_json_with_raw_newline_sanitized():
53
- output = '[{"file": "e.py", "line": 3, "message": "line1\nline2"}]'
54
- result = InlineCommentService.parse_model_output(output)
55
- assert len(result.root) == 1
56
- assert result.root[0].file == "e.py"
57
- assert result.root[0].line == 3
58
- assert result.root[0].message == "line1\nline2"
59
-
60
-
61
- def test_json_with_tab_character_sanitized():
62
- output = '[{"file": "f.py", "line": 4, "message": "a\tb"}]'
63
- result = InlineCommentService.parse_model_output(output)
64
- assert len(result.root) == 1
65
- assert result.root[0].message == "a\tb"
66
-
67
-
68
- def test_json_with_null_byte_sanitized():
69
- raw = "abc\0def"
70
- output = f'[{{"file": "g.py", "line": 5, "message": "{raw}"}}]'
71
- result = InlineCommentService.parse_model_output(output)
72
- assert len(result.root) == 1
73
- assert result.root[0].message == "abc\0def"
74
-
75
-
76
- def test_json_with_multiple_control_chars():
77
- raw = "x\n\ry\t\0z"
78
- output = f'[{{"file": "h.py", "line": 6, "message": "{raw}"}}]'
79
- result = InlineCommentService.parse_model_output(output)
80
- assert len(result.root) == 1
81
- assert result.root[0].message == "x\n\ry\t\0z"
82
-
83
-
84
- def test_try_parse_valid_json():
85
- raw = '[{"file": "ok.py", "line": 1, "message": "all good"}]'
86
- result = InlineCommentService.try_parse_model_output(raw)
87
- assert isinstance(result, InlineCommentListSchema)
88
- assert len(result.root) == 1
89
- assert result.root[0].file == "ok.py"
90
- assert result.root[0].line == 1
91
- assert result.root[0].message == "all good"
92
-
93
-
94
- def test_try_parse_needs_sanitization():
95
- raw = '[{"file": "bad.py", "line": 2, "message": "line1\nline2"}]'
96
- result = InlineCommentService.try_parse_model_output(raw)
97
- assert result is not None
98
- assert result.root[0].file == "bad.py"
99
- assert result.root[0].line == 2
100
- assert result.root[0].message == "line1\nline2"
101
- assert "line1" in result.root[0].message
102
-
103
-
104
- def test_try_parse_totally_invalid_returns_none():
105
- raw = "this is not json at all"
106
- result = InlineCommentService.try_parse_model_output(raw)
107
- assert result is None