xai-review 0.10.0__py3-none-any.whl → 0.12.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.
- ai_review/libs/config/prompt.py +1 -0
- ai_review/libs/json.py +6 -9
- ai_review/services/prompt/service.py +19 -18
- ai_review/services/prompt/tools.py +24 -0
- ai_review/services/review/inline/service.py +2 -2
- ai_review/tests/suites/libs/test_json.py +2 -16
- ai_review/tests/suites/services/prompt/test_service.py +33 -0
- ai_review/tests/suites/services/prompt/test_tools.py +72 -0
- ai_review/tests/suites/services/review/inline/test_service.py +6 -0
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/METADATA +1 -1
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/RECORD +15 -13
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/WHEEL +0 -0
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/entry_points.txt +0 -0
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/licenses/LICENSE +0 -0
- {xai_review-0.10.0.dist-info → xai_review-0.12.0.dist-info}/top_level.txt +0 -0
ai_review/libs/config/prompt.py
CHANGED
|
@@ -8,6 +8,7 @@ from ai_review.libs.resources import load_resource
|
|
|
8
8
|
|
|
9
9
|
class PromptConfig(BaseModel):
|
|
10
10
|
context: dict[str, str] = Field(default_factory=dict)
|
|
11
|
+
normalize_prompts: bool = True
|
|
11
12
|
context_placeholder: str = "<<{value}>>"
|
|
12
13
|
inline_prompt_files: list[FilePath] | None = None
|
|
13
14
|
context_prompt_files: list[FilePath] | None = None
|
ai_review/libs/json.py
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import re
|
|
2
2
|
|
|
3
3
|
CONTROL_CHARS_RE = re.compile(r"[\x00-\x1F]")
|
|
4
|
+
REPLACEMENTS = {
|
|
5
|
+
"\n": "\\n",
|
|
6
|
+
"\r": "\\r",
|
|
7
|
+
"\t": "\\t",
|
|
8
|
+
}
|
|
4
9
|
|
|
5
10
|
|
|
6
11
|
def sanitize_json_string(raw: str) -> str:
|
|
7
12
|
def replace(match: re.Match) -> str:
|
|
8
13
|
char = match.group()
|
|
9
|
-
|
|
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}"
|
|
14
|
+
return REPLACEMENTS.get(char, f"\\u{ord(char):04x}")
|
|
18
15
|
|
|
19
16
|
return CONTROL_CHARS_RE.sub(replace, raw)
|
|
@@ -1,56 +1,57 @@
|
|
|
1
1
|
from ai_review.config import settings
|
|
2
2
|
from ai_review.services.diff.schema import DiffFileSchema
|
|
3
3
|
from ai_review.services.prompt.schema import PromptContextSchema
|
|
4
|
+
from ai_review.services.prompt.tools import normalize_prompt, format_file
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
class PromptService:
|
|
8
|
+
@classmethod
|
|
9
|
+
def prepare_prompt(cls, prompts: list[str], context: PromptContextSchema) -> str:
|
|
10
|
+
prompt = "\n\n".join(prompts)
|
|
11
|
+
prompt = context.apply_format(prompt)
|
|
8
12
|
|
|
13
|
+
if settings.prompt.normalize_prompts:
|
|
14
|
+
prompt = normalize_prompt(prompt)
|
|
15
|
+
|
|
16
|
+
return prompt
|
|
9
17
|
|
|
10
|
-
class PromptService:
|
|
11
18
|
@classmethod
|
|
12
19
|
def build_inline_request(cls, diff: DiffFileSchema, context: PromptContextSchema) -> str:
|
|
13
|
-
|
|
14
|
-
inline_prompts = context.apply_format(inline_prompts)
|
|
20
|
+
prompt = cls.prepare_prompt(settings.prompt.load_inline(), context)
|
|
15
21
|
return (
|
|
16
|
-
f"{
|
|
22
|
+
f"{prompt}\n\n"
|
|
17
23
|
f"## Diff\n\n"
|
|
18
24
|
f"{format_file(diff)}"
|
|
19
25
|
)
|
|
20
26
|
|
|
21
27
|
@classmethod
|
|
22
28
|
def build_summary_request(cls, diffs: list[DiffFileSchema], context: PromptContextSchema) -> str:
|
|
29
|
+
prompt = cls.prepare_prompt(settings.prompt.load_summary(), context)
|
|
23
30
|
changes = "\n\n".join(map(format_file, diffs))
|
|
24
|
-
summary_prompts = "\n\n".join(settings.prompt.load_summary())
|
|
25
|
-
summary_prompts = context.apply_format(summary_prompts)
|
|
26
31
|
return (
|
|
27
|
-
f"{
|
|
32
|
+
f"{prompt}\n\n"
|
|
28
33
|
f"## Changes\n\n"
|
|
29
34
|
f"{changes}\n"
|
|
30
35
|
)
|
|
31
36
|
|
|
32
37
|
@classmethod
|
|
33
38
|
def build_context_request(cls, diffs: list[DiffFileSchema], context: PromptContextSchema) -> str:
|
|
39
|
+
prompt = cls.prepare_prompt(settings.prompt.load_context(), context)
|
|
34
40
|
changes = "\n\n".join(map(format_file, diffs))
|
|
35
|
-
inline_prompts = "\n\n".join(settings.prompt.load_context())
|
|
36
|
-
inline_prompts = context.apply_format(inline_prompts)
|
|
37
41
|
return (
|
|
38
|
-
f"{
|
|
42
|
+
f"{prompt}\n\n"
|
|
39
43
|
f"## Diff\n\n"
|
|
40
44
|
f"{changes}\n"
|
|
41
45
|
)
|
|
42
46
|
|
|
43
47
|
@classmethod
|
|
44
48
|
def build_system_inline_request(cls, context: PromptContextSchema) -> str:
|
|
45
|
-
|
|
46
|
-
return context.apply_format(prompt)
|
|
49
|
+
return cls.prepare_prompt(settings.prompt.load_system_inline(), context)
|
|
47
50
|
|
|
48
51
|
@classmethod
|
|
49
52
|
def build_system_context_request(cls, context: PromptContextSchema) -> str:
|
|
50
|
-
|
|
51
|
-
return context.apply_format(prompt)
|
|
53
|
+
return cls.prepare_prompt(settings.prompt.load_system_context(), context)
|
|
52
54
|
|
|
53
55
|
@classmethod
|
|
54
56
|
def build_system_summary_request(cls, context: PromptContextSchema) -> str:
|
|
55
|
-
|
|
56
|
-
return context.apply_format(prompt)
|
|
57
|
+
return cls.prepare_prompt(settings.prompt.load_system_summary(), context)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from ai_review.libs.logger import get_logger
|
|
4
|
+
from ai_review.services.diff.schema import DiffFileSchema
|
|
5
|
+
|
|
6
|
+
logger = get_logger("PROMPT_TOOLS")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def format_file(diff: DiffFileSchema) -> str:
|
|
10
|
+
return f"# File: {diff.file}\n{diff.diff}\n"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def normalize_prompt(text: str) -> str:
|
|
14
|
+
tails_stripped = [re.sub(r"[ \t]+$", "", line) for line in text.splitlines()]
|
|
15
|
+
text = "\n".join(tails_stripped)
|
|
16
|
+
|
|
17
|
+
text = re.sub(r"\n{3,}", "\n\n", text)
|
|
18
|
+
|
|
19
|
+
result = text.strip()
|
|
20
|
+
if len(text) > len(result):
|
|
21
|
+
logger.info(f"Prompt has been normalized from {len(text)} to {len(result)}")
|
|
22
|
+
return result
|
|
23
|
+
|
|
24
|
+
return text
|
|
@@ -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.
|
|
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.
|
|
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"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
+
from ai_review.config import settings
|
|
3
4
|
from ai_review.libs.config.prompt import PromptConfig
|
|
4
5
|
from ai_review.services.diff.schema import DiffFileSchema
|
|
5
6
|
from ai_review.services.prompt.schema import PromptContextSchema
|
|
@@ -134,3 +135,35 @@ def test_diff_placeholders_are_not_replaced(dummy_context: PromptContextSchema)
|
|
|
134
135
|
|
|
135
136
|
assert "<<merge_request_title>>" in result
|
|
136
137
|
assert "Fix login bug" not in result
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_prepare_prompt_basic_substitution(dummy_context: PromptContextSchema) -> None:
|
|
141
|
+
prompts = ["Hello", "MR title: <<merge_request_title>>"]
|
|
142
|
+
result = PromptService.prepare_prompt(prompts, dummy_context)
|
|
143
|
+
assert "Hello" in result
|
|
144
|
+
assert "MR title: Fix login bug" in result
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_prepare_prompt_applies_normalization(
|
|
148
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
149
|
+
dummy_context: PromptContextSchema
|
|
150
|
+
) -> None:
|
|
151
|
+
monkeypatch.setattr(settings.prompt, "normalize_prompts", True)
|
|
152
|
+
prompts = ["Line with space ", "", "", "Next line"]
|
|
153
|
+
result = PromptService.prepare_prompt(prompts, dummy_context)
|
|
154
|
+
|
|
155
|
+
assert "Line with space" in result
|
|
156
|
+
assert "Next line" in result
|
|
157
|
+
assert "\n\n\n" not in result
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_prepare_prompt_skips_normalization(
|
|
161
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
162
|
+
dummy_context: PromptContextSchema
|
|
163
|
+
) -> None:
|
|
164
|
+
monkeypatch.setattr(settings.prompt, "normalize_prompts", False)
|
|
165
|
+
prompts = ["Line with space ", "", "", "Next line"]
|
|
166
|
+
result = PromptService.prepare_prompt(prompts, dummy_context)
|
|
167
|
+
|
|
168
|
+
assert "Line with space " in result
|
|
169
|
+
assert "\n\n\n" in result
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from ai_review.services.diff.schema import DiffFileSchema
|
|
2
|
+
from ai_review.services.prompt.tools import format_file, normalize_prompt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_format_file_basic():
|
|
6
|
+
diff = DiffFileSchema(file="main.py", diff="+ print('hello')")
|
|
7
|
+
result = format_file(diff)
|
|
8
|
+
assert result == "# File: main.py\n+ print('hello')\n"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_format_file_empty_diff():
|
|
12
|
+
diff = DiffFileSchema(file="empty.py", diff="")
|
|
13
|
+
result = format_file(diff)
|
|
14
|
+
assert result == "# File: empty.py\n\n"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_format_file_multiline_diff():
|
|
18
|
+
diff = DiffFileSchema(
|
|
19
|
+
file="utils/helpers.py",
|
|
20
|
+
diff="- old line\n+ new line\n+ another line"
|
|
21
|
+
)
|
|
22
|
+
result = format_file(diff)
|
|
23
|
+
expected = (
|
|
24
|
+
"# File: utils/helpers.py\n"
|
|
25
|
+
"- old line\n"
|
|
26
|
+
"+ new line\n"
|
|
27
|
+
"+ another line\n"
|
|
28
|
+
)
|
|
29
|
+
assert result == expected
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_format_file_filename_with_path():
|
|
33
|
+
diff = DiffFileSchema(file="src/app/models/user.py", diff="+ class User:")
|
|
34
|
+
result = format_file(diff)
|
|
35
|
+
assert result.startswith("# File: src/app/models/user.py\n")
|
|
36
|
+
assert result.endswith("+ class User:\n")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_trailing_spaces_are_removed():
|
|
40
|
+
text = "hello \nworld\t\t"
|
|
41
|
+
result = normalize_prompt(text)
|
|
42
|
+
assert result == "hello\nworld"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_multiple_empty_lines_collapsed():
|
|
46
|
+
text = "line1\n\n\n\nline2"
|
|
47
|
+
result = normalize_prompt(text)
|
|
48
|
+
assert result == "line1\n\nline2"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_leading_and_trailing_whitespace_removed():
|
|
52
|
+
text = "\n\n hello\nworld \n\n"
|
|
53
|
+
result = normalize_prompt(text)
|
|
54
|
+
assert result == "hello\nworld"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_internal_spaces_preserved():
|
|
58
|
+
text = "foo bar\nbaz\t\tqux"
|
|
59
|
+
result = normalize_prompt(text)
|
|
60
|
+
assert result == "foo bar\nbaz\t\tqux"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_only_whitespace_string():
|
|
64
|
+
text = " \n \n"
|
|
65
|
+
result = normalize_prompt(text)
|
|
66
|
+
assert result == ""
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_no_changes_when_already_clean():
|
|
70
|
+
text = "line1\nline2"
|
|
71
|
+
result = normalize_prompt(text)
|
|
72
|
+
assert result == text
|
|
@@ -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
|
|
|
@@ -26,7 +26,7 @@ ai_review/clients/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
26
26
|
ai_review/clients/openai/client.py,sha256=N07ZRnbptOtab8imMUZbGL-kRoOwIZmNYbHySumD3IU,1707
|
|
27
27
|
ai_review/clients/openai/schema.py,sha256=glxwMtBrDA6W0BQgH-ruKe0bKH3Ps1P-Y1-2jGdqaUM,764
|
|
28
28
|
ai_review/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
ai_review/libs/json.py,sha256=
|
|
29
|
+
ai_review/libs/json.py,sha256=g-P5_pNUomQ-bGHCXASvPKj9Og0s9MaLFVEAkzqGp1A,350
|
|
30
30
|
ai_review/libs/logger.py,sha256=LbXR2Zk1btJ-83I-vHee7cUETgT1mHToSsqEI_8uM0U,370
|
|
31
31
|
ai_review/libs/resources.py,sha256=s9taAbL1Shl_GiGkPpkkivUcM1Yh6d_IQAG97gffsJU,748
|
|
32
32
|
ai_review/libs/asynchronous/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -41,7 +41,7 @@ ai_review/libs/config/http.py,sha256=QsIj0yH1IYELOFBQ5AoqPZT0kGIIrQ19cxk1ozPRhLE
|
|
|
41
41
|
ai_review/libs/config/llm.py,sha256=cK-e4NCQxnnixLATCsO8-r5k3zUWz1N0BdPCoqerORM,1824
|
|
42
42
|
ai_review/libs/config/logger.py,sha256=oPmjpjf6EZwW7CgOjT8mOQdGnT98CLwXepiGB_ajZvU,384
|
|
43
43
|
ai_review/libs/config/openai.py,sha256=vOYqhUq0ceEuNdQrQaHq44lVS5M648mB61Zc4YlfJVw,271
|
|
44
|
-
ai_review/libs/config/prompt.py,sha256=
|
|
44
|
+
ai_review/libs/config/prompt.py,sha256=8aO5WNnhVhQcpWzWxqzb9lq6PzormaJazVwPHuf_ia8,4469
|
|
45
45
|
ai_review/libs/config/review.py,sha256=LEZni68iH_0m4URPfN0d3F6yrrK7KSn-BwXf-7w2al8,1058
|
|
46
46
|
ai_review/libs/config/vcs.py,sha256=FduvJJkGObh2LgTSapaMB6FABIvjX7E63yTwZF4p8CU,517
|
|
47
47
|
ai_review/libs/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -98,12 +98,13 @@ ai_review/services/llm/openai/client.py,sha256=WhMXNfH_G1NTlFkdRK5sgYvrCIE5ZQNfP
|
|
|
98
98
|
ai_review/services/prompt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
99
99
|
ai_review/services/prompt/adapter.py,sha256=humGHLRVBu0JspeULgYHCs782BAy4YYKSf5yaG8aF24,1003
|
|
100
100
|
ai_review/services/prompt/schema.py,sha256=erAecUYzOWyZfixt-pjmPSnvcMDh5DajMd1b7_SPm_o,2052
|
|
101
|
-
ai_review/services/prompt/service.py,sha256=
|
|
101
|
+
ai_review/services/prompt/service.py,sha256=D1PR2HC4cgrEND6mAhU5EPRAtp4mgEkOLEyD51WBc0g,2129
|
|
102
|
+
ai_review/services/prompt/tools.py,sha256=-gS74mVM3OZPKWQkY9_QfStkfxaUfssDbJ3Bdi4AQ74,636
|
|
102
103
|
ai_review/services/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
104
|
ai_review/services/review/service.py,sha256=8YhRFqhZAk2pAnkDaytKSCENlOeOti1brAJq3R9tVMY,8394
|
|
104
105
|
ai_review/services/review/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
106
|
ai_review/services/review/inline/schema.py,sha256=ry8sJdTgusQvFW51neRiapzgzVGwswwJzdYhaV3hbT0,1545
|
|
106
|
-
ai_review/services/review/inline/service.py,sha256=
|
|
107
|
+
ai_review/services/review/inline/service.py,sha256=34I3eK2Ra1l3aUvSYfO-Wx9aPfcgCWqTgjdoGHlNO08,2135
|
|
107
108
|
ai_review/services/review/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
109
|
ai_review/services/review/policy/service.py,sha256=yGDePLxAEF3N1Pkh47jGVd-4dGEESyxDXIXxV7KQfuY,2027
|
|
109
110
|
ai_review/services/review/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -131,7 +132,7 @@ ai_review/tests/suites/clients/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
131
132
|
ai_review/tests/suites/clients/openai/test_client.py,sha256=Ox5ifP1C_gSeDRacBa9DnXhe__Z8-WcbzR2JH_V3xKo,1050
|
|
132
133
|
ai_review/tests/suites/clients/openai/test_schema.py,sha256=x1tamS4GC9pOTpjieKDbK2D73CVV4BkATppytwMevLo,1599
|
|
133
134
|
ai_review/tests/suites/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
134
|
-
ai_review/tests/suites/libs/test_json.py,sha256=
|
|
135
|
+
ai_review/tests/suites/libs/test_json.py,sha256=q_tvFcL9EaN5jr48Ed_mxMEmW6xXS0xlZGqSooPZBa4,713
|
|
135
136
|
ai_review/tests/suites/libs/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
136
137
|
ai_review/tests/suites/libs/config/test_prompt.py,sha256=kDMTnykC54tTPfE6cqYRBbV8d5jzAKucXdJfwtqUybM,2242
|
|
137
138
|
ai_review/tests/suites/libs/diff/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -147,19 +148,20 @@ ai_review/tests/suites/services/diff/test_service.py,sha256=iFkGX9Vj2X44JU3eFsoH
|
|
|
147
148
|
ai_review/tests/suites/services/diff/test_tools.py,sha256=HBQ3eCn-kLeb_k5iTgyr09x0VwLYSegSbxm0Qk9ZrCc,3543
|
|
148
149
|
ai_review/tests/suites/services/prompt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
149
150
|
ai_review/tests/suites/services/prompt/test_schema.py,sha256=XkJk4N9ovgod7G3i6oZwRBjpd71sv0vtVDJhSOfIwGA,2660
|
|
150
|
-
ai_review/tests/suites/services/prompt/test_service.py,sha256=
|
|
151
|
+
ai_review/tests/suites/services/prompt/test_service.py,sha256=plJ8xDnBifCrLtHJO00cdl11U1EsqSw7lBrEGxu0AIw,6752
|
|
152
|
+
ai_review/tests/suites/services/prompt/test_tools.py,sha256=_yNZoBATvPU5enWNIopbjY8lVVjfaB_46kNIKODhCW4,1981
|
|
151
153
|
ai_review/tests/suites/services/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
152
154
|
ai_review/tests/suites/services/review/inline/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
153
155
|
ai_review/tests/suites/services/review/inline/test_schema.py,sha256=tIz-1UA_GgwcdsyUqgrodiiVVmd_jhoOVmtEwzRVWiY,2474
|
|
154
|
-
ai_review/tests/suites/services/review/inline/test_service.py,sha256=
|
|
156
|
+
ai_review/tests/suites/services/review/inline/test_service.py,sha256=x8d-dhw_uEXtGVLDVv4xVodmscrXIfDkoAnG4UapdlQ,3815
|
|
155
157
|
ai_review/tests/suites/services/review/policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
156
158
|
ai_review/tests/suites/services/review/policy/test_service.py,sha256=kRWT550OjWYQ7ZfsihBRc-tx-NMkhlynEsqur55RK0M,3687
|
|
157
159
|
ai_review/tests/suites/services/review/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
158
160
|
ai_review/tests/suites/services/review/summary/test_schema.py,sha256=xSoydvABZldHaVDa0OBFvYrj8wMuZqUDN3MO-XdvxOI,819
|
|
159
161
|
ai_review/tests/suites/services/review/summary/test_service.py,sha256=8UMvi_NL9frm280vD6Q1NCDrdI7K8YbXzoViIus-I2g,541
|
|
160
|
-
xai_review-0.
|
|
161
|
-
xai_review-0.
|
|
162
|
-
xai_review-0.
|
|
163
|
-
xai_review-0.
|
|
164
|
-
xai_review-0.
|
|
165
|
-
xai_review-0.
|
|
162
|
+
xai_review-0.12.0.dist-info/licenses/LICENSE,sha256=p-v8m7Kmz4KKc7PcvsGiGEmCw9AiSXY4_ylOPy_u--Y,11343
|
|
163
|
+
xai_review-0.12.0.dist-info/METADATA,sha256=LCwEqar1dH6shbzNbIh4hZkuLcz0pOrhWz27Rta769I,9618
|
|
164
|
+
xai_review-0.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
165
|
+
xai_review-0.12.0.dist-info/entry_points.txt,sha256=JyC5URanMi5io5P_PXQf7H_I1OGIpk5cZQhaPQ0g4Zs,53
|
|
166
|
+
xai_review-0.12.0.dist-info/top_level.txt,sha256=sTsZbfzLoqvRZKdKa-BcxWvjlHdrpbeJ6DrGY0EuR0E,10
|
|
167
|
+
xai_review-0.12.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|