xai-review 0.10.0__tar.gz → 0.11.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 (171) hide show
  1. {xai_review-0.10.0 → xai_review-0.11.0}/PKG-INFO +1 -1
  2. xai_review-0.11.0/ai_review/libs/json.py +16 -0
  3. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/inline/service.py +2 -2
  4. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/test_json.py +2 -16
  5. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/inline/test_service.py +6 -0
  6. {xai_review-0.10.0 → xai_review-0.11.0}/pyproject.toml +1 -1
  7. {xai_review-0.10.0 → xai_review-0.11.0}/xai_review.egg-info/PKG-INFO +1 -1
  8. xai_review-0.10.0/ai_review/libs/json.py +0 -19
  9. {xai_review-0.10.0 → xai_review-0.11.0}/LICENSE +0 -0
  10. {xai_review-0.10.0 → xai_review-0.11.0}/README.md +0 -0
  11. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/__init__.py +0 -0
  12. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/__init__.py +0 -0
  13. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/commands/__init__.py +0 -0
  14. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/commands/run_context_review.py +0 -0
  15. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/commands/run_inline_review.py +0 -0
  16. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/commands/run_review.py +0 -0
  17. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/commands/run_summary_review.py +0 -0
  18. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/cli/main.py +0 -0
  19. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/__init__.py +0 -0
  20. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/claude/__init__.py +0 -0
  21. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/claude/client.py +0 -0
  22. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/claude/schema.py +0 -0
  23. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gemini/__init__.py +0 -0
  24. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gemini/client.py +0 -0
  25. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gemini/schema.py +0 -0
  26. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/__init__.py +0 -0
  27. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/client.py +0 -0
  28. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
  29. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/client.py +0 -0
  30. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
  31. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
  32. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/schema/comments.py +0 -0
  33. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/gitlab/mr/schema/discussions.py +0 -0
  34. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/openai/__init__.py +0 -0
  35. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/openai/client.py +0 -0
  36. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/clients/openai/schema.py +0 -0
  37. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/config.py +0 -0
  38. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/__init__.py +0 -0
  39. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/asynchronous/__init__.py +0 -0
  40. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/asynchronous/gather.py +0 -0
  41. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/__init__.py +0 -0
  42. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/artifacts.py +0 -0
  43. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/base.py +0 -0
  44. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/claude.py +0 -0
  45. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/gemini.py +0 -0
  46. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/gitlab.py +0 -0
  47. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/http.py +0 -0
  48. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/llm.py +0 -0
  49. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/logger.py +0 -0
  50. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/openai.py +0 -0
  51. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/prompt.py +0 -0
  52. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/review.py +0 -0
  53. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/config/vcs.py +0 -0
  54. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/constants/__init__.py +0 -0
  55. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/constants/llm_provider.py +0 -0
  56. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/constants/vcs_provider.py +0 -0
  57. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/diff/__init__.py +0 -0
  58. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/diff/models.py +0 -0
  59. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/diff/parser.py +0 -0
  60. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/diff/tools.py +0 -0
  61. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/__init__.py +0 -0
  62. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/client.py +0 -0
  63. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/event_hooks/__init__.py +0 -0
  64. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/event_hooks/base.py +0 -0
  65. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
  66. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/handlers.py +0 -0
  67. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/transports/__init__.py +0 -0
  68. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/http/transports/retry.py +0 -0
  69. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/logger.py +0 -0
  70. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/resources.py +0 -0
  71. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/template/__init__.py +0 -0
  72. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/libs/template/render.py +0 -0
  73. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/__init__.py +0 -0
  74. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_context.md +0 -0
  75. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_inline.md +0 -0
  76. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_summary.md +0 -0
  77. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_system_context.md +0 -0
  78. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_system_inline.md +0 -0
  79. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/prompts/default_system_summary.md +0 -0
  80. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/resources/__init__.py +0 -0
  81. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/resources/pricing.yaml +0 -0
  82. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/__init__.py +0 -0
  83. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/artifacts/__init__.py +0 -0
  84. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/artifacts/schema.py +0 -0
  85. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/artifacts/service.py +0 -0
  86. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/artifacts/tools.py +0 -0
  87. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/cost/__init__.py +0 -0
  88. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/cost/schema.py +0 -0
  89. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/cost/service.py +0 -0
  90. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/diff/__init__.py +0 -0
  91. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/diff/renderers.py +0 -0
  92. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/diff/schema.py +0 -0
  93. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/diff/service.py +0 -0
  94. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/diff/tools.py +0 -0
  95. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/git/__init__.py +0 -0
  96. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/git/service.py +0 -0
  97. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/git/types.py +0 -0
  98. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/__init__.py +0 -0
  99. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/claude/__init__.py +0 -0
  100. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/claude/client.py +0 -0
  101. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/factory.py +0 -0
  102. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/gemini/__init__.py +0 -0
  103. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/gemini/client.py +0 -0
  104. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/openai/__init__.py +0 -0
  105. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/openai/client.py +0 -0
  106. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/llm/types.py +0 -0
  107. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/prompt/__init__.py +0 -0
  108. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/prompt/adapter.py +0 -0
  109. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/prompt/schema.py +0 -0
  110. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/prompt/service.py +0 -0
  111. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/__init__.py +0 -0
  112. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/inline/__init__.py +0 -0
  113. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/inline/schema.py +0 -0
  114. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/policy/__init__.py +0 -0
  115. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/policy/service.py +0 -0
  116. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/service.py +0 -0
  117. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/summary/__init__.py +0 -0
  118. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/summary/schema.py +0 -0
  119. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/review/summary/service.py +0 -0
  120. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/vcs/__init__.py +0 -0
  121. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/vcs/factory.py +0 -0
  122. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/vcs/gitlab/__init__.py +0 -0
  123. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/vcs/gitlab/client.py +0 -0
  124. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/services/vcs/types.py +0 -0
  125. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/__init__.py +0 -0
  126. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/fixtures/__init__.py +0 -0
  127. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/fixtures/git.py +0 -0
  128. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/__init__.py +0 -0
  129. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/__init__.py +0 -0
  130. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/claude/__init__.py +0 -0
  131. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
  132. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
  133. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/gemini/__init__.py +0 -0
  134. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
  135. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
  136. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/gitlab/__init__.py +0 -0
  137. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
  138. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/openai/__init__.py +0 -0
  139. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/openai/test_client.py +0 -0
  140. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/clients/openai/test_schema.py +0 -0
  141. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/__init__.py +0 -0
  142. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/config/__init__.py +0 -0
  143. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
  144. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/diff/__init__.py +0 -0
  145. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
  146. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
  147. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
  148. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/template/__init__.py +0 -0
  149. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
  150. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/__init__.py +0 -0
  151. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/diff/__init__.py +0 -0
  152. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
  153. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
  154. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
  155. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/prompt/__init__.py +0 -0
  156. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
  157. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
  158. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/__init__.py +0 -0
  159. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/inline/__init__.py +0 -0
  160. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/inline/test_schema.py +0 -0
  161. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/policy/__init__.py +0 -0
  162. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/policy/test_service.py +0 -0
  163. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/summary/__init__.py +0 -0
  164. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/summary/test_schema.py +0 -0
  165. {xai_review-0.10.0 → xai_review-0.11.0}/ai_review/tests/suites/services/review/summary/test_service.py +0 -0
  166. {xai_review-0.10.0 → xai_review-0.11.0}/setup.cfg +0 -0
  167. {xai_review-0.10.0 → xai_review-0.11.0}/xai_review.egg-info/SOURCES.txt +0 -0
  168. {xai_review-0.10.0 → xai_review-0.11.0}/xai_review.egg-info/dependency_links.txt +0 -0
  169. {xai_review-0.10.0 → xai_review-0.11.0}/xai_review.egg-info/entry_points.txt +0 -0
  170. {xai_review-0.10.0 → xai_review-0.11.0}/xai_review.egg-info/requires.txt +0 -0
  171. {xai_review-0.10.0 → xai_review-0.11.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.10.0
3
+ Version: 0.11.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>
@@ -0,0 +1,16 @@
1
+ import re
2
+
3
+ CONTROL_CHARS_RE = re.compile(r"[\x00-\x1F]")
4
+ REPLACEMENTS = {
5
+ "\n": "\\n",
6
+ "\r": "\\r",
7
+ "\t": "\\t",
8
+ }
9
+
10
+
11
+ def sanitize_json_string(raw: str) -> str:
12
+ def replace(match: re.Match) -> str:
13
+ char = match.group()
14
+ return REPLACEMENTS.get(char, f"\\u{ord(char):04x}")
15
+
16
+ return CONTROL_CHARS_RE.sub(replace, raw)
@@ -18,12 +18,12 @@ class InlineCommentService:
18
18
  try:
19
19
  return InlineCommentListSchema.model_validate_json(raw)
20
20
  except ValidationError as error:
21
- logger.debug(f"Parse failed, trying sanitized JSON: {raw[:200]=}, {error=}")
21
+ logger.warning(f"Parse failed, trying sanitized JSON: {raw[:200]=}, {error=}")
22
22
  try:
23
23
  cleaned = sanitize_json_string(raw)
24
24
  return InlineCommentListSchema.model_validate_json(cleaned)
25
25
  except ValidationError as error:
26
- logger.debug(f"Sanitized JSON still invalid: {raw[:200]=}, {error=}")
26
+ logger.warning(f"Sanitized JSON still invalid: {raw[:200]=}, {error=}")
27
27
  return None
28
28
 
29
29
  @classmethod
@@ -12,30 +12,16 @@ from ai_review.libs.json import sanitize_json_string
12
12
  ("a\tb", "a\\tb"),
13
13
  ("abc\0def", "abc\\u0000def"),
14
14
  ("x\n\ry\t\0z", "x\\n\\ry\\t\\u0000z"),
15
+ ("\n\r\t\0", "\\n\\r\\t\\u0000"),
16
+ ("", "")
15
17
  ],
16
18
  )
17
19
  def test_sanitize_basic_cases(actual: str, expected: str) -> None:
18
20
  assert sanitize_json_string(actual) == expected
19
21
 
20
22
 
21
- def test_sanitize_multiple_control_chars() -> None:
22
- raw = "A\nB\rC\tD\0E"
23
- result = sanitize_json_string(raw)
24
- assert result == "A\\nB\\rC\\tD\\u0000E"
25
-
26
-
27
23
  def test_sanitize_idempotent() -> None:
28
24
  raw = "foo\nbar"
29
25
  once = sanitize_json_string(raw)
30
26
  twice = sanitize_json_string(once)
31
27
  assert once == twice
32
-
33
-
34
- def test_sanitize_empty_string() -> None:
35
- assert sanitize_json_string("") == ""
36
-
37
-
38
- def test_sanitize_only_control_chars() -> None:
39
- raw = "\n\r\t\0"
40
- result = sanitize_json_string(raw)
41
- assert result == "\\n\\r\\t\\u0000"
@@ -53,6 +53,8 @@ def test_json_with_raw_newline_sanitized():
53
53
  output = '[{"file": "e.py", "line": 3, "message": "line1\nline2"}]'
54
54
  result = InlineCommentService.parse_model_output(output)
55
55
  assert len(result.root) == 1
56
+ assert result.root[0].file == "e.py"
57
+ assert result.root[0].line == 3
56
58
  assert result.root[0].message == "line1\nline2"
57
59
 
58
60
 
@@ -85,6 +87,8 @@ def test_try_parse_valid_json():
85
87
  assert isinstance(result, InlineCommentListSchema)
86
88
  assert len(result.root) == 1
87
89
  assert result.root[0].file == "ok.py"
90
+ assert result.root[0].line == 1
91
+ assert result.root[0].message == "all good"
88
92
 
89
93
 
90
94
  def test_try_parse_needs_sanitization():
@@ -92,6 +96,8 @@ def test_try_parse_needs_sanitization():
92
96
  result = InlineCommentService.try_parse_model_output(raw)
93
97
  assert result is not None
94
98
  assert result.root[0].file == "bad.py"
99
+ assert result.root[0].line == 2
100
+ assert result.root[0].message == "line1\nline2"
95
101
  assert "line1" in result.root[0].message
96
102
 
97
103
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "xai-review"
7
7
  readme = "README.md"
8
- version = "0.10.0"
8
+ version = "0.11.0"
9
9
  license = { text = "Apache-2.0" }
10
10
  authors = [
11
11
  { name = "Nikita Filonov", email = "nikita.filonov@example.com" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xai-review
3
- Version: 0.10.0
3
+ Version: 0.11.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>
@@ -1,19 +0,0 @@
1
- import re
2
-
3
- CONTROL_CHARS_RE = re.compile(r"[\x00-\x1F]")
4
-
5
-
6
- def sanitize_json_string(raw: str) -> str:
7
- def replace(match: re.Match) -> str:
8
- char = match.group()
9
- match char:
10
- case "\n":
11
- return "\\n"
12
- case "\r":
13
- return "\\r"
14
- case "\t":
15
- return "\\t"
16
- case _:
17
- return f"\\u{ord(char):04x}"
18
-
19
- return CONTROL_CHARS_RE.sub(replace, raw)
File without changes
File without changes
File without changes