xai-review 0.31.0__py3-none-any.whl → 0.33.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/clients/gitea/pr/schema/comments.py +0 -2
- ai_review/services/artifacts/tools.py +2 -2
- ai_review/services/vcs/gitea/client.py +25 -34
- ai_review/tests/fixtures/clients/gitea.py +0 -2
- ai_review/tests/fixtures/services/artifacts.py +6 -0
- ai_review/tests/suites/services/artifacts/__init__.py +0 -0
- ai_review/tests/suites/services/artifacts/test_service.py +92 -0
- ai_review/tests/suites/services/artifacts/test_tools.py +28 -0
- ai_review/tests/suites/services/vcs/gitea/test_client.py +11 -10
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/METADATA +2 -2
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/RECORD +15 -12
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/WHEEL +0 -0
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/entry_points.txt +0 -0
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/licenses/LICENSE +0 -0
- {xai_review-0.31.0.dist-info → xai_review-0.33.0.dist-info}/top_level.txt +0 -0
|
@@ -28,8 +28,6 @@ class GiteaGetPRCommentsResponseSchema(RootModel[list[GiteaPRCommentSchema]]):
|
|
|
28
28
|
|
|
29
29
|
class GiteaCreateCommentRequestSchema(BaseModel):
|
|
30
30
|
body: str
|
|
31
|
-
path: str | None = None
|
|
32
|
-
line: int | None = None
|
|
33
31
|
|
|
34
32
|
|
|
35
33
|
class GiteaCreateCommentResponseSchema(BaseModel):
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import hashlib
|
|
2
|
-
from datetime import datetime
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def make_artifact_id(text: str) -> str:
|
|
6
6
|
sha = hashlib.sha1(text.encode()).hexdigest()[:8]
|
|
7
|
-
ts = datetime.
|
|
7
|
+
ts = datetime.now(timezone.utc).strftime("%Y.%m.%d_%H-%M-%S")
|
|
8
8
|
return f"{ts}_{sha}"
|
|
@@ -2,7 +2,10 @@ from ai_review.clients.gitea.client import get_gitea_http_client
|
|
|
2
2
|
from ai_review.clients.gitea.pr.schema.comments import GiteaCreateCommentRequestSchema
|
|
3
3
|
from ai_review.config import settings
|
|
4
4
|
from ai_review.libs.logger import get_logger
|
|
5
|
-
from ai_review.services.vcs.gitea.adapter import
|
|
5
|
+
from ai_review.services.vcs.gitea.adapter import (
|
|
6
|
+
get_user_from_gitea_user,
|
|
7
|
+
get_review_comment_from_gitea_comment,
|
|
8
|
+
)
|
|
6
9
|
from ai_review.services.vcs.types import (
|
|
7
10
|
VCSClientProtocol,
|
|
8
11
|
ThreadKind,
|
|
@@ -67,12 +70,13 @@ class GiteaVCSClient(VCSClientProtocol):
|
|
|
67
70
|
return []
|
|
68
71
|
|
|
69
72
|
async def get_inline_comments(self) -> list[ReviewCommentSchema]:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
comments = await self.get_general_comments()
|
|
74
|
+
if comments:
|
|
75
|
+
logger.warning(
|
|
76
|
+
f"Gitea API does not support inline comments — "
|
|
77
|
+
f"returning {len(comments)} general comments as fallback inline comments"
|
|
78
|
+
)
|
|
79
|
+
return comments
|
|
76
80
|
|
|
77
81
|
async def create_general_comment(self, message: str) -> None:
|
|
78
82
|
try:
|
|
@@ -90,25 +94,15 @@ class GiteaVCSClient(VCSClientProtocol):
|
|
|
90
94
|
raise
|
|
91
95
|
|
|
92
96
|
async def create_inline_comment(self, file: str, line: int, message: str) -> None:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)
|
|
100
|
-
await self.http_client.pr.create_comment(
|
|
101
|
-
owner=self.owner,
|
|
102
|
-
repo=self.repo,
|
|
103
|
-
pull_number=self.pull_number,
|
|
104
|
-
request=request,
|
|
105
|
-
)
|
|
106
|
-
logger.info(f"Created inline comment in {self.pull_request_ref} at {file}:{line}")
|
|
107
|
-
except Exception as error:
|
|
108
|
-
logger.exception(f"Failed to create inline comment in {self.pull_request_ref} at {file}:{line}: {error}")
|
|
109
|
-
raise
|
|
97
|
+
fallback_message = f"[{file}:{line}] {message}"
|
|
98
|
+
logger.warning(
|
|
99
|
+
f"Gitea does not support inline comments. "
|
|
100
|
+
f"Falling back to general comment: {fallback_message}"
|
|
101
|
+
)
|
|
102
|
+
await self.create_general_comment(fallback_message)
|
|
110
103
|
|
|
111
104
|
async def create_inline_reply(self, thread_id: int | str, message: str) -> None:
|
|
105
|
+
logger.warning("Gitea does not support threaded replies — posting new general comment instead")
|
|
112
106
|
await self.create_general_comment(message)
|
|
113
107
|
|
|
114
108
|
async def create_summary_reply(self, thread_id: int | str, message: str) -> None:
|
|
@@ -118,17 +112,15 @@ class GiteaVCSClient(VCSClientProtocol):
|
|
|
118
112
|
async def get_inline_threads(self) -> list[ReviewThreadSchema]:
|
|
119
113
|
try:
|
|
120
114
|
comments = await self.get_inline_comments()
|
|
121
|
-
threads = {comment.thread_id: [comment] for comment in comments}
|
|
122
|
-
|
|
123
115
|
return [
|
|
124
116
|
ReviewThreadSchema(
|
|
125
|
-
id=thread_id,
|
|
117
|
+
id=comment.thread_id,
|
|
126
118
|
kind=ThreadKind.INLINE,
|
|
127
|
-
file=
|
|
128
|
-
line=
|
|
129
|
-
comments=
|
|
119
|
+
file=comment.file,
|
|
120
|
+
line=comment.line,
|
|
121
|
+
comments=[comment],
|
|
130
122
|
)
|
|
131
|
-
for
|
|
123
|
+
for comment in comments
|
|
132
124
|
]
|
|
133
125
|
except Exception as error:
|
|
134
126
|
logger.exception(f"Failed to build inline threads for {self.pull_request_ref}: {error}")
|
|
@@ -137,15 +129,14 @@ class GiteaVCSClient(VCSClientProtocol):
|
|
|
137
129
|
async def get_general_threads(self) -> list[ReviewThreadSchema]:
|
|
138
130
|
try:
|
|
139
131
|
comments = await self.get_general_comments()
|
|
140
|
-
|
|
132
|
+
return [
|
|
141
133
|
ReviewThreadSchema(
|
|
142
134
|
id=comment.thread_id,
|
|
143
135
|
kind=ThreadKind.SUMMARY,
|
|
144
|
-
comments=[comment]
|
|
136
|
+
comments=[comment],
|
|
145
137
|
)
|
|
146
138
|
for comment in comments
|
|
147
139
|
]
|
|
148
|
-
return threads
|
|
149
140
|
except Exception as error:
|
|
150
141
|
logger.exception(f"Failed to build general threads for {self.pull_request_ref}: {error}")
|
|
151
142
|
return []
|
|
@@ -45,13 +45,11 @@ class FakeGiteaPullRequestsHTTPClient(GiteaPullRequestsHTTPClientProtocol):
|
|
|
45
45
|
return GiteaGetPRFilesResponseSchema(
|
|
46
46
|
root=[
|
|
47
47
|
GiteaPRFileSchema(
|
|
48
|
-
sha="abc",
|
|
49
48
|
status="modified",
|
|
50
49
|
filename="src/main.py",
|
|
51
50
|
patch="@@ -1,2 +1,2 @@\n- old\n+ new",
|
|
52
51
|
),
|
|
53
52
|
GiteaPRFileSchema(
|
|
54
|
-
sha="def",
|
|
55
53
|
status="added",
|
|
56
54
|
filename="utils/helper.py",
|
|
57
55
|
patch="+ print('Hello')",
|
|
@@ -2,6 +2,7 @@ from pathlib import Path
|
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
|
+
from ai_review.services.artifacts.service import ArtifactsService
|
|
5
6
|
from ai_review.services.artifacts.types import ArtifactsServiceProtocol
|
|
6
7
|
|
|
7
8
|
|
|
@@ -49,3 +50,8 @@ class FakeArtifactsService(ArtifactsServiceProtocol):
|
|
|
49
50
|
@pytest.fixture
|
|
50
51
|
def fake_artifacts_service() -> FakeArtifactsService:
|
|
51
52
|
return FakeArtifactsService()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.fixture
|
|
56
|
+
def artifacts_service() -> ArtifactsService:
|
|
57
|
+
return ArtifactsService()
|
|
File without changes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import aiofiles
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from ai_review.config import settings
|
|
8
|
+
from ai_review.libs.config.artifacts import ArtifactsConfig
|
|
9
|
+
from ai_review.services.artifacts.service import ArtifactsService
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.asyncio
|
|
13
|
+
async def test_save_llm_interaction_creates_file(
|
|
14
|
+
tmp_path: Path,
|
|
15
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
16
|
+
artifacts_service: ArtifactsService
|
|
17
|
+
):
|
|
18
|
+
"""Checks that a JSON file is created with the correct name and content when LLM saving is enabled."""
|
|
19
|
+
monkeypatch.setattr(settings, "artifacts", ArtifactsConfig(llm_dir=tmp_path, llm_enabled=True))
|
|
20
|
+
|
|
21
|
+
artifact_id = await artifacts_service.save_llm_interaction(
|
|
22
|
+
prompt="Hello world",
|
|
23
|
+
prompt_system="system prompt",
|
|
24
|
+
response="model answer"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
assert artifact_id is not None
|
|
28
|
+
artifact_path = tmp_path / f"{artifact_id}.json"
|
|
29
|
+
assert artifact_path.exists(), "Artifact file was not created"
|
|
30
|
+
|
|
31
|
+
async with aiofiles.open(artifact_path, "r", encoding="utf-8") as file:
|
|
32
|
+
content = await file.read()
|
|
33
|
+
data = json.loads(content)
|
|
34
|
+
assert data["id"] == artifact_id
|
|
35
|
+
assert data["prompt"] == "Hello world"
|
|
36
|
+
assert data["response"] == "model answer"
|
|
37
|
+
assert data["prompt_system"] == "system prompt"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.mark.asyncio
|
|
41
|
+
async def test_save_llm_interaction_disabled(
|
|
42
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
43
|
+
artifacts_service: ArtifactsService
|
|
44
|
+
):
|
|
45
|
+
"""Checks that the method returns None and does not create a file if LLM saving is disabled."""
|
|
46
|
+
monkeypatch.setattr(settings, "artifacts", ArtifactsConfig(llm_enabled=False))
|
|
47
|
+
|
|
48
|
+
artifact_id = await artifacts_service.save_llm_interaction(
|
|
49
|
+
prompt="ignored",
|
|
50
|
+
prompt_system="ignored",
|
|
51
|
+
response="ignored"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
assert artifact_id is None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.mark.asyncio
|
|
58
|
+
async def test_save_artifact_writes_file(tmp_path: Path, artifacts_service: ArtifactsService):
|
|
59
|
+
"""Checks that save_artifact writes content to the given file path."""
|
|
60
|
+
file_path = tmp_path / "test.json"
|
|
61
|
+
content = '{"key": "value"}'
|
|
62
|
+
|
|
63
|
+
result = await artifacts_service.save_artifact(file=file_path, content=content, kind="test")
|
|
64
|
+
|
|
65
|
+
assert result == file_path
|
|
66
|
+
assert file_path.exists()
|
|
67
|
+
async with aiofiles.open(file_path, "r", encoding="utf-8") as f:
|
|
68
|
+
saved_content = await f.read()
|
|
69
|
+
assert saved_content == content
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@pytest.mark.asyncio
|
|
73
|
+
async def test_save_artifact_handles_exception(
|
|
74
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
75
|
+
artifacts_service: ArtifactsService
|
|
76
|
+
):
|
|
77
|
+
"""Checks that save_artifact gracefully returns None on write error."""
|
|
78
|
+
|
|
79
|
+
class BrokenAsyncFile:
|
|
80
|
+
async def __aenter__(self):
|
|
81
|
+
raise OSError("disk full")
|
|
82
|
+
|
|
83
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
monkeypatch.setattr(
|
|
87
|
+
"ai_review.services.artifacts.service.aiofiles.open",
|
|
88
|
+
lambda *args, **kwargs: BrokenAsyncFile()
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
result = await artifacts_service.save_artifact(Path("/fake/path.json"), "data")
|
|
92
|
+
assert result is None
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from ai_review.services.artifacts.tools import make_artifact_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.parametrize("text", ["hello", "some longer text", ""])
|
|
10
|
+
def test_make_artifact_id_format_and_sha(text: str):
|
|
11
|
+
"""Checks that the function returns a valid artifact ID format and correct SHA prefix."""
|
|
12
|
+
artifact_id = make_artifact_id(text)
|
|
13
|
+
|
|
14
|
+
pattern = r"^\d{4}\.\d{2}\.\d{2}_\d{2}-\d{2}-\d{2}_[0-9a-f]{8}$"
|
|
15
|
+
assert re.match(pattern, artifact_id), f"Invalid format: {artifact_id}"
|
|
16
|
+
|
|
17
|
+
expected_sha = hashlib.sha1(text.encode()).hexdigest()[:8]
|
|
18
|
+
assert artifact_id.endswith(expected_sha)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_make_artifact_id_is_deterministic_for_same_input():
|
|
22
|
+
"""Checks that the SHA part is deterministic (identical for the same input)."""
|
|
23
|
+
sha1 = hashlib.sha1("repeatable".encode()).hexdigest()[:8]
|
|
24
|
+
artifact_id1 = make_artifact_id("repeatable")
|
|
25
|
+
artifact_id2 = make_artifact_id("repeatable")
|
|
26
|
+
|
|
27
|
+
assert artifact_id1.split("_")[2] == sha1
|
|
28
|
+
assert artifact_id2.split("_")[2] == sha1
|
|
@@ -29,19 +29,20 @@ async def test_get_general_comments_returns_list(
|
|
|
29
29
|
fake_gitea_pull_requests_http_client: FakeGiteaPullRequestsHTTPClient,
|
|
30
30
|
):
|
|
31
31
|
comments = await gitea_vcs_client.get_general_comments()
|
|
32
|
-
assert all(isinstance(
|
|
32
|
+
assert all(isinstance(comment, ReviewCommentSchema) for comment in comments)
|
|
33
33
|
assert len(comments) > 0
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
@pytest.mark.asyncio
|
|
37
37
|
@pytest.mark.usefixtures("gitea_http_client_config")
|
|
38
|
-
async def
|
|
38
|
+
async def test_get_inline_comments_returns_fallback_general_comments(
|
|
39
39
|
gitea_vcs_client: GiteaVCSClient,
|
|
40
40
|
fake_gitea_pull_requests_http_client: FakeGiteaPullRequestsHTTPClient,
|
|
41
41
|
):
|
|
42
42
|
comments = await gitea_vcs_client.get_inline_comments()
|
|
43
|
-
assert
|
|
44
|
-
assert all(isinstance(
|
|
43
|
+
assert isinstance(comments, list)
|
|
44
|
+
assert all(isinstance(comment, ReviewCommentSchema) for comment in comments)
|
|
45
|
+
assert len(comments) > 0
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
@pytest.mark.asyncio
|
|
@@ -57,11 +58,11 @@ async def test_create_general_comment_posts_comment(
|
|
|
57
58
|
|
|
58
59
|
@pytest.mark.asyncio
|
|
59
60
|
@pytest.mark.usefixtures("gitea_http_client_config")
|
|
60
|
-
async def
|
|
61
|
+
async def test_create_inline_comment_falls_back_to_general_comment(
|
|
61
62
|
gitea_vcs_client: GiteaVCSClient,
|
|
62
63
|
fake_gitea_pull_requests_http_client: FakeGiteaPullRequestsHTTPClient,
|
|
63
64
|
):
|
|
64
|
-
await gitea_vcs_client.create_inline_comment("src/main.py", 10, "Inline comment")
|
|
65
|
+
await gitea_vcs_client.create_inline_comment(file="src/main.py", line=10, message="Inline comment")
|
|
65
66
|
calls = [name for name, _ in fake_gitea_pull_requests_http_client.calls]
|
|
66
67
|
assert "create_comment" in calls
|
|
67
68
|
|
|
@@ -72,8 +73,8 @@ async def test_get_inline_threads_groups_by_comment(
|
|
|
72
73
|
gitea_vcs_client: GiteaVCSClient,
|
|
73
74
|
):
|
|
74
75
|
threads = await gitea_vcs_client.get_inline_threads()
|
|
75
|
-
assert all(isinstance(
|
|
76
|
-
assert all(
|
|
76
|
+
assert all(isinstance(thread, ReviewThreadSchema) for thread in threads)
|
|
77
|
+
assert all(thread.kind == ThreadKind.INLINE for thread in threads)
|
|
77
78
|
|
|
78
79
|
|
|
79
80
|
@pytest.mark.asyncio
|
|
@@ -82,5 +83,5 @@ async def test_get_general_threads_wraps_comments(
|
|
|
82
83
|
gitea_vcs_client: GiteaVCSClient,
|
|
83
84
|
):
|
|
84
85
|
threads = await gitea_vcs_client.get_general_threads()
|
|
85
|
-
assert all(isinstance(
|
|
86
|
-
assert all(
|
|
86
|
+
assert all(isinstance(thread, ReviewThreadSchema) for thread in threads)
|
|
87
|
+
assert all(thread.kind == ThreadKind.SUMMARY for thread in threads)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xai-review
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.33.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>
|
|
@@ -220,7 +220,7 @@ jobs:
|
|
|
220
220
|
with:
|
|
221
221
|
fetch-depth: 0
|
|
222
222
|
|
|
223
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
223
|
+
- uses: Nikita-Filonov/ai-review@v0.33.0
|
|
224
224
|
with:
|
|
225
225
|
review-command: ${{ inputs.review-command }}
|
|
226
226
|
env:
|
|
@@ -36,7 +36,7 @@ ai_review/clients/gitea/pr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
36
36
|
ai_review/clients/gitea/pr/client.py,sha256=eFAZai2zinr7ZGscVHa0cZIaYJJucNcLb08f73cKo-o,4945
|
|
37
37
|
ai_review/clients/gitea/pr/types.py,sha256=hy4win_nDvnEi_aHAbysmHtymHDq-zIATYKSEbpDcYY,984
|
|
38
38
|
ai_review/clients/gitea/pr/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
ai_review/clients/gitea/pr/schema/comments.py,sha256=
|
|
39
|
+
ai_review/clients/gitea/pr/schema/comments.py,sha256=Xf07Z3PwuWiL9-xQtJ5QIrrorAwOyveD8yaaGAAIJiQ,866
|
|
40
40
|
ai_review/clients/gitea/pr/schema/files.py,sha256=O4c4Z3R775OuGOJgf5baMH5ivzHCVsSBFaPXEgVmKs0,341
|
|
41
41
|
ai_review/clients/gitea/pr/schema/pull_request.py,sha256=lT4r-Am5MmFQqB5WnQ0OWw6cB3e-NlBAi08Jw1fmAE8,361
|
|
42
42
|
ai_review/clients/gitea/pr/schema/user.py,sha256=5YIys_MFFm612hKMMQdjwlsH-FG_bS-vSQsPbBueEPU,94
|
|
@@ -137,7 +137,7 @@ ai_review/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
|
137
137
|
ai_review/services/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
138
|
ai_review/services/artifacts/schema.py,sha256=o4dqG5LFCdAQY3wjRF5rImANe-X20g4zX_bCIKiHLSk,291
|
|
139
139
|
ai_review/services/artifacts/service.py,sha256=SDHwYm9I4pSPISyNWqHEOR-wTTEa5ThsIi458C9hBt8,1789
|
|
140
|
-
ai_review/services/artifacts/tools.py,sha256=
|
|
140
|
+
ai_review/services/artifacts/tools.py,sha256=KrCQxbBEBIgqUhxZwCmbj1f07B5403gkfSgpS9qLpE4,242
|
|
141
141
|
ai_review/services/artifacts/types.py,sha256=VPEDuQQciyQL8qcmgFuZxZUuuh2-xLwqwxmNZr62F3E,448
|
|
142
142
|
ai_review/services/cost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
143
|
ai_review/services/cost/schema.py,sha256=K3uCIMMxGL8AaIPh4a-d0mT5uIJuk3f805DkP8o8DtY,1323
|
|
@@ -215,7 +215,7 @@ ai_review/services/vcs/bitbucket/adapter.py,sha256=b-8KT46C8WT-Sos-gUGFJsxIWY7mX
|
|
|
215
215
|
ai_review/services/vcs/bitbucket/client.py,sha256=MhqkFDewutX7DFBCFBDhDopFznwf92dAdZsxy_oS_mc,10726
|
|
216
216
|
ai_review/services/vcs/gitea/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
217
|
ai_review/services/vcs/gitea/adapter.py,sha256=DxzcXReKTGHkw4DCJa8X3Mnczcg9hqx6sIAQYY-8HAI,784
|
|
218
|
-
ai_review/services/vcs/gitea/client.py,sha256=
|
|
218
|
+
ai_review/services/vcs/gitea/client.py,sha256=A2qpuk5kiPyeaPt-hYv0PcC_VlshMHhycED2nmB9bOE,5776
|
|
219
219
|
ai_review/services/vcs/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
220
220
|
ai_review/services/vcs/github/adapter.py,sha256=pxcbSLEXkOg1c1NtzB0hkZJVvyC4An9pCzNK5sPJKbA,1212
|
|
221
221
|
ai_review/services/vcs/github/client.py,sha256=rSVvpyovT1wDLq0fIQPe5UJqmgIgIFh2P-CPqIQ_sf0,9371
|
|
@@ -228,7 +228,7 @@ ai_review/tests/fixtures/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
228
228
|
ai_review/tests/fixtures/clients/bitbucket.py,sha256=K4Ez_hTOVKz5-KlXbgTOVDec6iewxkm8hqDJvebhnpE,7124
|
|
229
229
|
ai_review/tests/fixtures/clients/claude.py,sha256=6ldJlSSea0zsZV0hRDMi9mqWm0hWT3mp_ROwG_sVU1c,2203
|
|
230
230
|
ai_review/tests/fixtures/clients/gemini.py,sha256=zhLJhm49keKEBCPOf_pLu8_zCatsKKAWM4-gXOhaXeM,2429
|
|
231
|
-
ai_review/tests/fixtures/clients/gitea.py,sha256=
|
|
231
|
+
ai_review/tests/fixtures/clients/gitea.py,sha256=WQLbOyFTqqtVQGHuLFgk9qANYS03eeCdY6dtN3a7fIE,4965
|
|
232
232
|
ai_review/tests/fixtures/clients/github.py,sha256=kC1L-nWZMn9O_uRfuT_B8R4sn8FRvISlBJMkRKaioS0,7814
|
|
233
233
|
ai_review/tests/fixtures/clients/gitlab.py,sha256=AD6NJOJSw76hjAEiWewQ6Vu5g-cfQn0GTtdchuDBH9o,8042
|
|
234
234
|
ai_review/tests/fixtures/clients/ollama.py,sha256=UUHDDPUraQAG8gBC-0UvftaK0BDYir5cJDlRKJymSQg,2109
|
|
@@ -237,7 +237,7 @@ ai_review/tests/fixtures/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
237
237
|
ai_review/tests/fixtures/libs/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
238
238
|
ai_review/tests/fixtures/libs/llm/output_json_parser.py,sha256=Eu0tCK5cD1d9X1829ruahih7jQoehGozIEugS71AAA8,275
|
|
239
239
|
ai_review/tests/fixtures/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
240
|
-
ai_review/tests/fixtures/services/artifacts.py,sha256=
|
|
240
|
+
ai_review/tests/fixtures/services/artifacts.py,sha256=ETxcGT27YUSegSjxKuuXx1B8ZCXmAm0hhUzW5Vqt7Os,1621
|
|
241
241
|
ai_review/tests/fixtures/services/cost.py,sha256=A6Ja0CtQ-k6pR2-B5LRE8EzkqPL34xHGXYtaILjhYvw,1612
|
|
242
242
|
ai_review/tests/fixtures/services/diff.py,sha256=rOLFR-giYJlE2qUYTOT9BxyJhQ-fbXDdYCw3zed4-9M,1471
|
|
243
243
|
ai_review/tests/fixtures/services/git.py,sha256=zDNNLZDoVC7r4LuF1N1MUgzhcAl2nhDdFC9olpR_PjQ,1441
|
|
@@ -308,6 +308,9 @@ ai_review/tests/suites/libs/llm/test_output_json_parser.py,sha256=2KwnXZc3dlUWM1
|
|
|
308
308
|
ai_review/tests/suites/libs/template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
309
309
|
ai_review/tests/suites/libs/template/test_render.py,sha256=n-ss5bd_hwc-RzYmqWmFM6KSlP1zLSnlsW1Yki12Bpw,1890
|
|
310
310
|
ai_review/tests/suites/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
311
|
+
ai_review/tests/suites/services/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
312
|
+
ai_review/tests/suites/services/artifacts/test_service.py,sha256=OFYHORgvKVLXrAWImTUs9nXAuAUGUVQT-QBZPU3WjVc,3054
|
|
313
|
+
ai_review/tests/suites/services/artifacts/test_tools.py,sha256=kvxGoCcL6JovW10GoVycKE5M3e-fkbVd6OpHLbPvhIA,1022
|
|
311
314
|
ai_review/tests/suites/services/cost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
312
315
|
ai_review/tests/suites/services/cost/test_schema.py,sha256=AI3Wg1sR6nzLpkEqJGDu6nDYwiwzbbghsxhRNwRsUFA,3044
|
|
313
316
|
ai_review/tests/suites/services/cost/test_service.py,sha256=9_Mi5hu2cq3w2tIEPfhrn9x8SblCT5m1W-QUOc9BZds,3258
|
|
@@ -366,16 +369,16 @@ ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py,sha256=zOjAOxtSSN0
|
|
|
366
369
|
ai_review/tests/suites/services/vcs/bitbucket/test_client.py,sha256=oIlUdUBPgO2bfNyAsodUsAU7kRnETQVqmRJimRtEfBU,7846
|
|
367
370
|
ai_review/tests/suites/services/vcs/gitea/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
368
371
|
ai_review/tests/suites/services/vcs/gitea/test_adapter.py,sha256=7UPsbDQhn99obPZZ2fKnLE3_h9uoY_ujMD0WbHGAegY,1782
|
|
369
|
-
ai_review/tests/suites/services/vcs/gitea/test_client.py,sha256=
|
|
372
|
+
ai_review/tests/suites/services/vcs/gitea/test_client.py,sha256=bUrc7QpqIgyehzYW4Yr5ewzNRzGAfvX2DQmx01GdYYo,3449
|
|
370
373
|
ai_review/tests/suites/services/vcs/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
371
374
|
ai_review/tests/suites/services/vcs/github/test_adapter.py,sha256=bK4k532v_8kDiud5RI9OlGetWMiLP8NaW1vEfHvcHfQ,4893
|
|
372
375
|
ai_review/tests/suites/services/vcs/github/test_client.py,sha256=mNt1bA6aVU3REsJiU_tK1PokQxQTaCKun0tNBHuvIp8,8039
|
|
373
376
|
ai_review/tests/suites/services/vcs/gitlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
374
377
|
ai_review/tests/suites/services/vcs/gitlab/test_adapter.py,sha256=BYBP2g1AKF_jCSJYJj16pW7M_6PprwD9reYEpdw3StU,4340
|
|
375
378
|
ai_review/tests/suites/services/vcs/gitlab/test_client.py,sha256=dnI-YxYADmVF2GS9rp6-JPkcqsn4sN8Fjbe4MkeYMaE,8476
|
|
376
|
-
xai_review-0.
|
|
377
|
-
xai_review-0.
|
|
378
|
-
xai_review-0.
|
|
379
|
-
xai_review-0.
|
|
380
|
-
xai_review-0.
|
|
381
|
-
xai_review-0.
|
|
379
|
+
xai_review-0.33.0.dist-info/licenses/LICENSE,sha256=p-v8m7Kmz4KKc7PcvsGiGEmCw9AiSXY4_ylOPy_u--Y,11343
|
|
380
|
+
xai_review-0.33.0.dist-info/METADATA,sha256=olP2J_qC--KQKEyDvq1JNIUtqgd029Lli6fiI6zKAc0,12689
|
|
381
|
+
xai_review-0.33.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
382
|
+
xai_review-0.33.0.dist-info/entry_points.txt,sha256=JyC5URanMi5io5P_PXQf7H_I1OGIpk5cZQhaPQ0g4Zs,53
|
|
383
|
+
xai_review-0.33.0.dist-info/top_level.txt,sha256=sTsZbfzLoqvRZKdKa-BcxWvjlHdrpbeJ6DrGY0EuR0E,10
|
|
384
|
+
xai_review-0.33.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|