coding-client 1.21.2__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.
- coding_client/__init__.py +1 -0
- coding_client/api/__init__.py +19 -0
- coding_client/api/exception_handlers.py +158 -0
- coding_client/api/logging_setup.py +44 -0
- coding_client/api/metrics.py +40 -0
- coding_client/api/openapi_config.py +124 -0
- coding_client/api/request_logging.py +60 -0
- coding_client/api/validation.py +150 -0
- coding_client/auth/__init__.py +78 -0
- coding_client/auth/_default_tenant.py +132 -0
- coding_client/auth/_header_trust.py +98 -0
- coding_client/auth/_onbehalf.py +315 -0
- coding_client/auth/_trusted_networks.py +94 -0
- coding_client/auth/dependencies.py +61 -0
- coding_client/auth/middleware.py +445 -0
- coding_client/auth/models.py +83 -0
- coding_client/auth/outbound.py +137 -0
- coding_client/auth/rbac.py +21 -0
- coding_client/auth/rbac_coding.py +5 -0
- coding_client/auth/tenant.py +650 -0
- coding_client/auth/websocket.py +148 -0
- coding_client/clients/__init__.py +24 -0
- coding_client/clients/base.py +131 -0
- coding_client/clients/coding_ai.py +33 -0
- coding_client/clients/coding_analysis.py +36 -0
- coding_client/clients/coding_containers.py +45 -0
- coding_client/clients/coding_github.py +127 -0
- coding_client/clients/coding_realtime.py +127 -0
- coding_client/clients/coding_security.py +51 -0
- coding_client/clients/coding_testing.py +31 -0
- coding_client/clients/coding_workspaces.py +265 -0
- coding_client/config/__init__.py +12 -0
- coding_client/config/base_settings.py +61 -0
- coding_client/config/yaml_config_loader.py +172 -0
- coding_client/db/__init__.py +42 -0
- coding_client/db/db_types.py +122 -0
- coding_client/db/exceptions.py +59 -0
- coding_client/db/postgres_connection.py +572 -0
- coding_client/db/tenant_query_helper.py +417 -0
- coding_client/db_init.py +49 -0
- coding_client/exceptions/__init__.py +67 -0
- coding_client/exceptions/api_exceptions.py +395 -0
- coding_client/exceptions/pydantic_ai_exceptions.py +533 -0
- coding_client/interfaces/__init__.py +22 -0
- coding_client/interfaces/cache_interface.py +179 -0
- coding_client/interfaces/container_interface.py +49 -0
- coding_client/interfaces/docker_interface.py +283 -0
- coding_client/interfaces/graph_interface.py +28 -0
- coding_client/interfaces/security_interface.py +72 -0
- coding_client/interfaces/webhook_interface.py +67 -0
- coding_client/llm/__init__.py +54 -0
- coding_client/llm/base_agent.py +195 -0
- coding_client/llm/context.py +121 -0
- coding_client/llm/responses.py +102 -0
- coding_client/llm/routing.py +82 -0
- coding_client/llm/settings.py +102 -0
- coding_client/models/__init__.py +62 -0
- coding_client/models/agent.py +38 -0
- coding_client/models/ai_test_failure.py +745 -0
- coding_client/models/analysis.py +330 -0
- coding_client/models/architecture.py +685 -0
- coding_client/models/bug.py +128 -0
- coding_client/models/code_graph.py +317 -0
- coding_client/models/container.py +241 -0
- coding_client/models/core.py +878 -0
- coding_client/models/docker_container.py +104 -0
- coding_client/models/github.py +293 -0
- coding_client/models/logging.py +29 -0
- coding_client/models/package_manager.py +257 -0
- coding_client/models/pr_validation.py +440 -0
- coding_client/models/pydantic_ai.py +395 -0
- coding_client/models/repo_scanner.py +249 -0
- coding_client/models/responses.py +431 -0
- coding_client/models/security.py +185 -0
- coding_client/models/static_analysis.py +508 -0
- coding_client/models/system.py +48 -0
- coding_client/models/test_executor.py +204 -0
- coding_client/models/testing.py +673 -0
- coding_client/models/testing_config.py +200 -0
- coding_client/models/validation.py +127 -0
- coding_client/models_init.py +272 -0
- coding_client/telemetry.py +195 -0
- coding_client/testing.py +180 -0
- coding_client/types/__init__.py +130 -0
- coding_client/types/constraint_types.py +276 -0
- coding_client/types/core_types.py +112 -0
- coding_client/types/state_machine.py +443 -0
- coding_client/utils/__init__.py +86 -0
- coding_client/utils/archive_utils.py +387 -0
- coding_client/utils/ast_debug.py +45 -0
- coding_client/utils/async_timeout.py +364 -0
- coding_client/utils/constants.py +518 -0
- coding_client/utils/content_processing.py +326 -0
- coding_client/utils/database.py +916 -0
- coding_client/utils/encoding_helper.py +222 -0
- coding_client/utils/enum_helpers.py +166 -0
- coding_client/utils/file_operations.py +177 -0
- coding_client/utils/filesystem_ops.py +528 -0
- coding_client/utils/http_client.py +562 -0
- coding_client/utils/path_utils.py +471 -0
- coding_client/utils/profiling.py +421 -0
- coding_client/utils/response_builder.py +240 -0
- coding_client/utils/retry_helper.py +712 -0
- coding_client/utils/security_validation.py +423 -0
- coding_client-1.21.2.dist-info/METADATA +234 -0
- coding_client-1.21.2.dist-info/RECORD +109 -0
- coding_client-1.21.2.dist-info/WHEEL +5 -0
- coding_client-1.21.2.dist-info/licenses/LICENSE +201 -0
- coding_client-1.21.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Docker-specific container models for internal container management.
|
|
2
|
+
|
|
3
|
+
This module provides Pydantic models that represent Docker containers and their
|
|
4
|
+
metadata within the code graph helper system. These models facilitate the management
|
|
5
|
+
of containerized development environments for code analysis.
|
|
6
|
+
|
|
7
|
+
The models in this module are specifically designed for internal use by the DockerService
|
|
8
|
+
and handle the conversion between Docker-specific representations and the public API models.
|
|
9
|
+
|
|
10
|
+
Classes:
|
|
11
|
+
DockerContainerDetails: Internal representation of a Docker container with all
|
|
12
|
+
Docker-specific metadata including ports, environment variables, and status.
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
```python
|
|
16
|
+
from docker_container_models import DockerContainerDetails, ContainerStatus
|
|
17
|
+
|
|
18
|
+
# Create container details
|
|
19
|
+
container = DockerContainerDetails(
|
|
20
|
+
docker_id="abc123",
|
|
21
|
+
container_name="my-analysis-container",
|
|
22
|
+
image="code-graph-helper:latest",
|
|
23
|
+
ports={"8700/tcp": 8700},
|
|
24
|
+
workspace_path="/app/workspace",
|
|
25
|
+
status=ContainerStatus.RUNNING
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Convert to public API model
|
|
29
|
+
api_model = container.to_container_info(
|
|
30
|
+
code_graph_id="graph-123",
|
|
31
|
+
repo_url="https://github.com/owner/repo"
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
from datetime import UTC, datetime
|
|
39
|
+
|
|
40
|
+
from pydantic import BaseModel, Field
|
|
41
|
+
|
|
42
|
+
from .container import ContainerInfo, ContainerStatus
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DockerContainerDetails(BaseModel):
|
|
46
|
+
"""Docker-specific container details for internal use by DockerService."""
|
|
47
|
+
|
|
48
|
+
docker_id: str
|
|
49
|
+
container_name: str
|
|
50
|
+
image: str
|
|
51
|
+
ports: dict[str, int]
|
|
52
|
+
environment: dict[str, str] = Field(default_factory=dict)
|
|
53
|
+
workspace_path: str
|
|
54
|
+
last_activity: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
|
55
|
+
status: ContainerStatus
|
|
56
|
+
|
|
57
|
+
def to_container_info(
|
|
58
|
+
self,
|
|
59
|
+
code_graph_id: str = "",
|
|
60
|
+
codebase_path: str = "/app/data/repo",
|
|
61
|
+
repo_url: str = "",
|
|
62
|
+
branch: str = "main",
|
|
63
|
+
description: str | None = None,
|
|
64
|
+
) -> ContainerInfo:
|
|
65
|
+
"""Convert Docker-specific details to public ContainerInfo model.
|
|
66
|
+
|
|
67
|
+
Transforms the internal Docker container representation into a public API model
|
|
68
|
+
that hides Docker-specific implementation details while providing essential
|
|
69
|
+
container information to API consumers.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
code_graph_id (str, optional): Unique identifier for the associated code graph.
|
|
73
|
+
Defaults to empty string.
|
|
74
|
+
codebase_path (str, optional): Path to the codebase within the container.
|
|
75
|
+
Defaults to "/app/data/repo".
|
|
76
|
+
repo_url (str, optional): URL of the repository being analyzed.
|
|
77
|
+
Defaults to empty string.
|
|
78
|
+
branch (str, optional): Git branch being analyzed.
|
|
79
|
+
Defaults to "main".
|
|
80
|
+
description (Optional[str], optional): Human-readable description of the container.
|
|
81
|
+
Defaults to None.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
ContainerInfo: Public API model containing essential container information
|
|
85
|
+
including the container name, API endpoint URL, and status.
|
|
86
|
+
|
|
87
|
+
Note:
|
|
88
|
+
The method extracts the first available port mapping from the Docker container
|
|
89
|
+
to construct the API endpoint URL. If no ports are mapped, it defaults to 8700.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
# Get the first port mapping (usually there's only one)
|
|
93
|
+
port = next(iter(self.ports.values()), 8700)
|
|
94
|
+
|
|
95
|
+
return ContainerInfo(
|
|
96
|
+
container_name=self.container_name,
|
|
97
|
+
api_endpoint=f"http://localhost:{port}",
|
|
98
|
+
code_graph_id=code_graph_id,
|
|
99
|
+
codebase_path=codebase_path,
|
|
100
|
+
repo_url=repo_url,
|
|
101
|
+
branch=branch,
|
|
102
|
+
status=self.status,
|
|
103
|
+
description=description,
|
|
104
|
+
)
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""GitHub integration models for repository operations and webhook handling.
|
|
2
|
+
|
|
3
|
+
This module provides comprehensive data models for GitHub API integration, supporting
|
|
4
|
+
repository operations, pull request management, webhook processing, and code analysis
|
|
5
|
+
workflows. The models facilitate seamless integration between GitHub's API and the
|
|
6
|
+
code graph helper system.
|
|
7
|
+
|
|
8
|
+
The GitHub integration supports:
|
|
9
|
+
- Repository cloning and synchronization
|
|
10
|
+
- Pull request analysis and validation
|
|
11
|
+
- Webhook event processing
|
|
12
|
+
- Code snippet evaluation in repository context
|
|
13
|
+
- Automated PR creation and management
|
|
14
|
+
- User and organization data handling
|
|
15
|
+
|
|
16
|
+
Key Model Categories:
|
|
17
|
+
Core GitHub Models: GitHubUser, GitHubRepository, GitHubCommit for basic entities
|
|
18
|
+
Pull Request Models: PullRequestData, PullRequest for PR operations
|
|
19
|
+
Webhook Models: GitHubWebhookPayload for event processing
|
|
20
|
+
Workspace Models: RepoWorkspace, RepoSetupResult for repository management
|
|
21
|
+
Request Models: SnippetAnalysisRequest, PRCreationRequest for API operations
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
```python
|
|
25
|
+
from github_models import GitHubRepository, PullRequestData, RepoSetupResult
|
|
26
|
+
|
|
27
|
+
# Repository information
|
|
28
|
+
repo = GitHubRepository(
|
|
29
|
+
id=123456,
|
|
30
|
+
name="my-project",
|
|
31
|
+
full_name="owner/my-project",
|
|
32
|
+
description="A sample project",
|
|
33
|
+
url="https://github.com/owner/my-project",
|
|
34
|
+
clone_url="https://github.com/owner/my-project.git",
|
|
35
|
+
default_branch="main",
|
|
36
|
+
language="Python",
|
|
37
|
+
size=1024,
|
|
38
|
+
stargazers_count=42,
|
|
39
|
+
forks_count=7,
|
|
40
|
+
open_issues_count=3,
|
|
41
|
+
private=False,
|
|
42
|
+
owner=GitHubUser(...)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Pull request data
|
|
46
|
+
pr = PullRequestData(
|
|
47
|
+
number=123,
|
|
48
|
+
title="Add new feature",
|
|
49
|
+
state="open",
|
|
50
|
+
author="contributor",
|
|
51
|
+
created_at=datetime.now(timezone.utc),
|
|
52
|
+
updated_at=datetime.now(timezone.utc),
|
|
53
|
+
base_branch="main",
|
|
54
|
+
head_branch="feature/new-feature",
|
|
55
|
+
url="https://github.com/owner/my-project/pull/123"
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
from __future__ import annotations
|
|
61
|
+
|
|
62
|
+
from datetime import datetime
|
|
63
|
+
from typing import Any
|
|
64
|
+
|
|
65
|
+
from pydantic import BaseModel, Field
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class PullRequestData(BaseModel):
|
|
69
|
+
"""Pull request data model."""
|
|
70
|
+
|
|
71
|
+
number: int = Field(..., description="Pull request number")
|
|
72
|
+
title: str = Field(..., description="Pull request title")
|
|
73
|
+
message: str | None = Field(None, description="Pull request message")
|
|
74
|
+
state: str = Field(..., description="Pull request state (open, closed, merged)")
|
|
75
|
+
author: str = Field(..., description="Pull request author")
|
|
76
|
+
created_at: datetime = Field(..., description="Creation timestamp")
|
|
77
|
+
updated_at: datetime = Field(..., description="Last update timestamp")
|
|
78
|
+
merged_at: datetime | None = Field(None, description="Merge timestamp")
|
|
79
|
+
base_branch: str = Field(..., description="Base branch")
|
|
80
|
+
head_branch: str = Field(..., description="Head branch")
|
|
81
|
+
url: str = Field(..., description="Pull request URL")
|
|
82
|
+
diff_url: str = Field(..., description="Diff URL")
|
|
83
|
+
patch_url: str = Field(..., description="Patch URL")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class GitHubUser(BaseModel):
|
|
87
|
+
"""GitHub user model."""
|
|
88
|
+
|
|
89
|
+
login: str = Field(..., description="Username")
|
|
90
|
+
id: int = Field(..., description="User ID")
|
|
91
|
+
avatar_url: str = Field(..., description="Avatar URL")
|
|
92
|
+
url: str = Field(..., description="User URL")
|
|
93
|
+
type: str = Field(..., description="User type")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class GitHubRepository(BaseModel):
|
|
97
|
+
"""GitHub repository model."""
|
|
98
|
+
|
|
99
|
+
id: int = Field(..., description="Repository ID")
|
|
100
|
+
name: str = Field(..., description="Repository name")
|
|
101
|
+
full_name: str = Field(..., description="Full repository name")
|
|
102
|
+
description: str | None = Field(None, description="Repository description")
|
|
103
|
+
url: str = Field(..., description="Repository URL")
|
|
104
|
+
clone_url: str = Field(..., description="Clone URL")
|
|
105
|
+
ssh_url: str = Field(..., description="SSH URL")
|
|
106
|
+
default_branch: str = Field(..., description="Default branch")
|
|
107
|
+
language: str | None = Field(None, description="Primary language")
|
|
108
|
+
size: int = Field(..., description="Repository size")
|
|
109
|
+
stargazers_count: int = Field(..., description="Number of stars")
|
|
110
|
+
forks_count: int = Field(..., description="Number of forks")
|
|
111
|
+
open_issues_count: int = Field(..., description="Number of open issues")
|
|
112
|
+
private: bool = Field(..., description="Whether repository is private")
|
|
113
|
+
owner: GitHubUser = Field(..., description="Repository owner")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class GitHubCommit(BaseModel):
|
|
117
|
+
"""GitHub commit model."""
|
|
118
|
+
|
|
119
|
+
sha: str = Field(..., description="Commit SHA")
|
|
120
|
+
message: str = Field(..., description="Commit message")
|
|
121
|
+
author: GitHubUser = Field(..., description="Commit author")
|
|
122
|
+
committer: GitHubUser = Field(..., description="Commit committer")
|
|
123
|
+
timestamp: datetime = Field(..., description="Commit timestamp")
|
|
124
|
+
url: str = Field(..., description="Commit URL")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class GitHubIssue(BaseModel):
|
|
128
|
+
"""GitHub issue model."""
|
|
129
|
+
|
|
130
|
+
number: int = Field(..., description="Issue number")
|
|
131
|
+
title: str = Field(..., description="Issue title")
|
|
132
|
+
message: str | None = Field(None, description="Issue message")
|
|
133
|
+
state: str = Field(..., description="Issue state")
|
|
134
|
+
author: GitHubUser = Field(..., description="Issue author")
|
|
135
|
+
assignees: list[GitHubUser] = Field(default_factory=list, description="Issue assignees")
|
|
136
|
+
labels: list[str] = Field(default_factory=list, description="Issue labels")
|
|
137
|
+
created_at: datetime = Field(..., description="Creation timestamp")
|
|
138
|
+
updated_at: datetime = Field(..., description="Last update timestamp")
|
|
139
|
+
closed_at: datetime | None = Field(None, description="Close timestamp")
|
|
140
|
+
url: str = Field(..., description="Issue URL")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class GitHubWebhookPayload(BaseModel):
|
|
144
|
+
"""GitHub webhook payload model."""
|
|
145
|
+
|
|
146
|
+
action: str = Field(..., description="Webhook action")
|
|
147
|
+
repository: GitHubRepository = Field(..., description="Repository data")
|
|
148
|
+
sender: GitHubUser = Field(..., description="Event sender")
|
|
149
|
+
pull_request: PullRequestData | None = Field(None, description="Pull request data")
|
|
150
|
+
issue: GitHubIssue | None = Field(None, description="Issue data")
|
|
151
|
+
commits: list[GitHubCommit] | None = Field(None, description="Commit data")
|
|
152
|
+
ref: str | None = Field(None, description="Git reference")
|
|
153
|
+
before: str | None = Field(None, description="Before SHA")
|
|
154
|
+
after: str | None = Field(None, description="After SHA")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# Additional GitHub-specific models (consolidated from github_dataclasses.py)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class GitHubRepoInfo(BaseModel):
|
|
161
|
+
"""GitHub repository information."""
|
|
162
|
+
|
|
163
|
+
owner: str = Field(..., description="Repository owner")
|
|
164
|
+
name: str = Field(..., description="Repository name")
|
|
165
|
+
url: str = Field(..., description="Repository URL")
|
|
166
|
+
default_branch: str = Field("main", description="Default branch")
|
|
167
|
+
description: str | None = Field(None, description="Repository description")
|
|
168
|
+
language: str | None = Field(None, description="Primary language")
|
|
169
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class CloneResult(BaseModel):
|
|
173
|
+
"""Result of repository cloning operation."""
|
|
174
|
+
|
|
175
|
+
success: bool = Field(..., description="Whether cloning was successful")
|
|
176
|
+
repo_id: str = Field(..., description="Repository identifier")
|
|
177
|
+
local_path: str = Field(..., description="Local path where repo was cloned")
|
|
178
|
+
error: str | None = Field(None, description="Error message if cloning failed")
|
|
179
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class SyncResult(BaseModel):
|
|
183
|
+
"""Result of repository synchronization."""
|
|
184
|
+
|
|
185
|
+
success: bool = Field(..., description="Whether sync was successful")
|
|
186
|
+
commits_behind: int = Field(0, description="Number of commits behind")
|
|
187
|
+
has_updates: bool = Field(False, description="Whether there are updates available")
|
|
188
|
+
error: str | None = Field(None, description="Error message if sync failed")
|
|
189
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class CodeSnippet(BaseModel):
|
|
193
|
+
"""Code snippet model for GitHub operations."""
|
|
194
|
+
|
|
195
|
+
code: str = Field(..., description="Code content")
|
|
196
|
+
language: str = Field(..., description="Programming language")
|
|
197
|
+
file_path: str | None = Field(None, description="File path")
|
|
198
|
+
line_number: int | None = Field(None, description="Line number")
|
|
199
|
+
description: str | None = Field(None, description="Code description")
|
|
200
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class RepositoryContext(BaseModel):
|
|
204
|
+
"""Context information about a repository."""
|
|
205
|
+
|
|
206
|
+
existing_patterns: list[dict[str, Any]] = Field(
|
|
207
|
+
default_factory=list, description="Existing code patterns"
|
|
208
|
+
)
|
|
209
|
+
style_guide: dict[str, Any] = Field(default_factory=dict, description="Style guide rules")
|
|
210
|
+
api_surface: dict[str, Any] = Field(default_factory=dict, description="API surface analysis")
|
|
211
|
+
size_metrics: dict[str, Any] = Field(
|
|
212
|
+
default_factory=dict, description="Repository size metrics"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class PRFileChange(BaseModel):
|
|
217
|
+
"""File change information for pull requests."""
|
|
218
|
+
|
|
219
|
+
file_path: str = Field(..., description="Path to changed file")
|
|
220
|
+
change_type: str = Field(..., description="Type of change (added, modified, deleted)")
|
|
221
|
+
content: str | None = Field(None, description="New file content")
|
|
222
|
+
old_content: str | None = Field(None, description="Previous file content")
|
|
223
|
+
additions: int = Field(0, description="Number of lines added")
|
|
224
|
+
deletions: int = Field(0, description="Number of lines deleted")
|
|
225
|
+
patch: str | None = Field(None, description="Git patch content")
|
|
226
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class PullRequest(BaseModel):
|
|
230
|
+
"""Pull request model for GitHub operations."""
|
|
231
|
+
|
|
232
|
+
id: str = Field(..., description="Pull request ID")
|
|
233
|
+
number: int = Field(..., description="Pull request number")
|
|
234
|
+
title: str = Field(..., description="Pull request title")
|
|
235
|
+
description: str = Field(..., description="Pull request description")
|
|
236
|
+
url: str = Field(..., description="Pull request URL")
|
|
237
|
+
status: str = Field(..., description="Pull request status")
|
|
238
|
+
created_at: datetime = Field(..., description="Creation timestamp")
|
|
239
|
+
updated_at: datetime | None = Field(None, description="Last update timestamp")
|
|
240
|
+
merged_at: datetime | None = Field(None, description="Merge timestamp")
|
|
241
|
+
author: str = Field(..., description="Pull request author")
|
|
242
|
+
base_branch: str = Field(..., description="Base branch")
|
|
243
|
+
head_branch: str = Field(..., description="Head branch")
|
|
244
|
+
labels: list[str] = Field(default_factory=list, description="Labels")
|
|
245
|
+
reviewers: list[str] = Field(default_factory=list, description="Reviewers")
|
|
246
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class RepoWorkspace(BaseModel):
|
|
250
|
+
"""Repository workspace model."""
|
|
251
|
+
|
|
252
|
+
repo_id: str = Field(..., description="Repository ID")
|
|
253
|
+
repo_url: str = Field(..., description="Repository URL")
|
|
254
|
+
local_path: str = Field(..., description="Local workspace path")
|
|
255
|
+
branch: str = Field("main", description="Current branch")
|
|
256
|
+
last_sync: datetime = Field(..., description="Last sync timestamp")
|
|
257
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class RepoSetupResult(BaseModel):
|
|
261
|
+
"""Result of repository setup operation."""
|
|
262
|
+
|
|
263
|
+
success: bool = Field(..., description="Whether setup was successful")
|
|
264
|
+
workspace: RepoWorkspace | None = Field(None, description="Created workspace")
|
|
265
|
+
error: str | None = Field(None, description="Error message if setup failed")
|
|
266
|
+
metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class SnippetAnalysisRequest(BaseModel):
|
|
270
|
+
"""Request for code snippet analysis."""
|
|
271
|
+
|
|
272
|
+
snippet: CodeSnippet = Field(..., description="Code snippet to analyze")
|
|
273
|
+
workspace_id: str = Field(..., description="Workspace ID for context")
|
|
274
|
+
context: dict[str, Any] = Field(default_factory=dict, description="Additional context")
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class SnippetEvaluationRequest(BaseModel):
|
|
278
|
+
"""Request for code snippet evaluation."""
|
|
279
|
+
|
|
280
|
+
workspace_id: str = Field(..., description="Workspace ID")
|
|
281
|
+
snippet: CodeSnippet = Field(..., description="Code snippet to evaluate")
|
|
282
|
+
evaluation_options: dict[str, Any] = Field(
|
|
283
|
+
default_factory=dict, description="Evaluation options"
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class PRCreationRequest(BaseModel):
|
|
288
|
+
"""Request for pull request creation."""
|
|
289
|
+
|
|
290
|
+
workspace_id: str = Field(..., description="Workspace ID")
|
|
291
|
+
changes: list[PRFileChange] = Field(..., description="File changes")
|
|
292
|
+
pr_data: PullRequestData = Field(..., description="Pull request data")
|
|
293
|
+
analysis_options: dict[str, Any] = Field(default_factory=dict, description="Analysis options")
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared logging models for the application.
|
|
3
|
+
|
|
4
|
+
This module provides common logging-related models used across different
|
|
5
|
+
components of the application to avoid duplication.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LogLevel(StrEnum):
|
|
14
|
+
"""Standard logging levels with clear hierarchy."""
|
|
15
|
+
|
|
16
|
+
DEBUG = "DEBUG"
|
|
17
|
+
INFO = "INFO"
|
|
18
|
+
WARNING = "WARNING"
|
|
19
|
+
ERROR = "ERROR"
|
|
20
|
+
CRITICAL = "CRITICAL"
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def from_lowercase(cls, value: str) -> LogLevel:
|
|
24
|
+
"""Convert lowercase log level to enum value."""
|
|
25
|
+
return cls(value.upper())
|
|
26
|
+
|
|
27
|
+
def to_lowercase(self) -> str:
|
|
28
|
+
"""Convert enum value to lowercase string."""
|
|
29
|
+
return self.value.lower()
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""Base models for package management across system and language package managers.
|
|
2
|
+
|
|
3
|
+
This module provides clear separation between system-level package managers
|
|
4
|
+
(apt, brew, yum) and language-specific package managers (pip, npm, cargo).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from enum import Enum
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SystemPackageManager(Enum):
|
|
15
|
+
"""System-level package managers for OS dependencies."""
|
|
16
|
+
|
|
17
|
+
# Linux distributions
|
|
18
|
+
APT = "apt-get" # Debian/Ubuntu
|
|
19
|
+
YUM = "yum" # RHEL/CentOS (older)
|
|
20
|
+
DNF = "dnf" # Fedora/RHEL/CentOS (newer)
|
|
21
|
+
PACMAN = "pacman" # Arch Linux
|
|
22
|
+
ZYPPER = "zypper" # openSUSE
|
|
23
|
+
APK = "apk" # Alpine Linux
|
|
24
|
+
|
|
25
|
+
# macOS
|
|
26
|
+
BREW = "brew" # Homebrew
|
|
27
|
+
|
|
28
|
+
# Windows
|
|
29
|
+
CHOCO = "choco" # Chocolatey
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def install_command(self) -> list[str]:
|
|
33
|
+
"""Get the base install command for this package manager."""
|
|
34
|
+
commands: dict[SystemPackageManager, list[str]] = {
|
|
35
|
+
SystemPackageManager.APT: ["sudo", "apt-get", "install", "-y"],
|
|
36
|
+
SystemPackageManager.YUM: ["sudo", "yum", "install", "-y"],
|
|
37
|
+
SystemPackageManager.DNF: ["sudo", "dnf", "install", "-y"],
|
|
38
|
+
SystemPackageManager.PACMAN: ["sudo", "pacman", "-S", "--noconfirm"],
|
|
39
|
+
SystemPackageManager.ZYPPER: ["sudo", "zypper", "install", "-y"],
|
|
40
|
+
SystemPackageManager.APK: ["sudo", "apk", "add"],
|
|
41
|
+
SystemPackageManager.BREW: ["brew", "install"],
|
|
42
|
+
SystemPackageManager.CHOCO: ["choco", "install", "-y"],
|
|
43
|
+
}
|
|
44
|
+
return commands.get(self, [])
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def update_command(self) -> list[str]:
|
|
48
|
+
"""Get the update command for this package manager."""
|
|
49
|
+
commands: dict[SystemPackageManager, list[str]] = {
|
|
50
|
+
SystemPackageManager.APT: ["sudo", "apt-get", "update"],
|
|
51
|
+
SystemPackageManager.YUM: ["sudo", "yum", "update", "-y"],
|
|
52
|
+
SystemPackageManager.DNF: ["sudo", "dnf", "update", "-y"],
|
|
53
|
+
SystemPackageManager.PACMAN: ["sudo", "pacman", "-Syu", "--noconfirm"],
|
|
54
|
+
SystemPackageManager.ZYPPER: ["sudo", "zypper", "refresh"],
|
|
55
|
+
SystemPackageManager.APK: ["sudo", "apk", "update"],
|
|
56
|
+
SystemPackageManager.BREW: ["brew", "update"],
|
|
57
|
+
SystemPackageManager.CHOCO: ["choco", "upgrade", "all", "-y"],
|
|
58
|
+
}
|
|
59
|
+
return commands.get(self, [])
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class LanguagePackageManager(Enum):
|
|
63
|
+
"""Language-specific package managers."""
|
|
64
|
+
|
|
65
|
+
# Python
|
|
66
|
+
PIP = "pip"
|
|
67
|
+
POETRY = "poetry"
|
|
68
|
+
PIPENV = "pipenv"
|
|
69
|
+
UV = "uv"
|
|
70
|
+
CONDA = "conda"
|
|
71
|
+
|
|
72
|
+
# JavaScript/TypeScript
|
|
73
|
+
NPM = "npm"
|
|
74
|
+
YARN = "yarn"
|
|
75
|
+
PNPM = "pnpm"
|
|
76
|
+
BUN = "bun"
|
|
77
|
+
|
|
78
|
+
# Rust
|
|
79
|
+
CARGO = "cargo"
|
|
80
|
+
|
|
81
|
+
# Java
|
|
82
|
+
MAVEN = "maven"
|
|
83
|
+
GRADLE = "gradle"
|
|
84
|
+
|
|
85
|
+
# Ruby
|
|
86
|
+
GEM = "gem"
|
|
87
|
+
BUNDLER = "bundler"
|
|
88
|
+
|
|
89
|
+
# Go
|
|
90
|
+
GO_MOD = "go mod"
|
|
91
|
+
|
|
92
|
+
# PHP
|
|
93
|
+
COMPOSER = "composer"
|
|
94
|
+
|
|
95
|
+
# .NET
|
|
96
|
+
NUGET = "nuget"
|
|
97
|
+
DOTNET = "dotnet"
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def manifest_files(self) -> list[str]:
|
|
101
|
+
"""Get typical manifest files for this package manager."""
|
|
102
|
+
manifests: dict[LanguagePackageManager, list[str]] = {
|
|
103
|
+
LanguagePackageManager.PIP: ["requirements.txt", "requirements/*.txt"],
|
|
104
|
+
LanguagePackageManager.POETRY: ["pyproject.toml", "poetry.lock"],
|
|
105
|
+
LanguagePackageManager.PIPENV: ["Pipfile", "Pipfile.lock"],
|
|
106
|
+
LanguagePackageManager.UV: ["pyproject.toml", "uv.lock"],
|
|
107
|
+
LanguagePackageManager.CONDA: ["environment.yml", "environment.yaml"],
|
|
108
|
+
LanguagePackageManager.NPM: ["package.json", "package-lock.json"],
|
|
109
|
+
LanguagePackageManager.YARN: ["package.json", "yarn.lock"],
|
|
110
|
+
LanguagePackageManager.PNPM: ["package.json", "pnpm-lock.yaml"],
|
|
111
|
+
LanguagePackageManager.BUN: ["package.json", "bun.lockb"],
|
|
112
|
+
LanguagePackageManager.CARGO: ["Cargo.toml", "Cargo.lock"],
|
|
113
|
+
LanguagePackageManager.MAVEN: ["pom.xml"],
|
|
114
|
+
LanguagePackageManager.GRADLE: ["build.gradle", "build.gradle.kts"],
|
|
115
|
+
LanguagePackageManager.GEM: ["Gemfile", "Gemfile.lock"],
|
|
116
|
+
LanguagePackageManager.BUNDLER: ["Gemfile", "Gemfile.lock"],
|
|
117
|
+
LanguagePackageManager.GO_MOD: ["go.mod", "go.sum"],
|
|
118
|
+
LanguagePackageManager.COMPOSER: ["composer.json", "composer.lock"],
|
|
119
|
+
LanguagePackageManager.NUGET: ["packages.config", "*.csproj"],
|
|
120
|
+
LanguagePackageManager.DOTNET: ["*.csproj", "*.fsproj", "*.vbproj"],
|
|
121
|
+
}
|
|
122
|
+
return manifests.get(self, [])
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def install_command(self) -> list[str]:
|
|
126
|
+
"""Get the install command for this package manager."""
|
|
127
|
+
commands: dict[LanguagePackageManager, list[str]] = {
|
|
128
|
+
LanguagePackageManager.PIP: ["pip", "install"],
|
|
129
|
+
LanguagePackageManager.POETRY: ["poetry", "install"],
|
|
130
|
+
LanguagePackageManager.PIPENV: ["pipenv", "install"],
|
|
131
|
+
LanguagePackageManager.UV: ["uv", "pip", "install"],
|
|
132
|
+
LanguagePackageManager.CONDA: ["conda", "install"],
|
|
133
|
+
LanguagePackageManager.NPM: ["npm", "install"],
|
|
134
|
+
LanguagePackageManager.YARN: ["yarn", "install"],
|
|
135
|
+
LanguagePackageManager.PNPM: ["pnpm", "install"],
|
|
136
|
+
LanguagePackageManager.BUN: ["bun", "install"],
|
|
137
|
+
LanguagePackageManager.CARGO: ["cargo", "build"],
|
|
138
|
+
LanguagePackageManager.MAVEN: ["mvn", "install"],
|
|
139
|
+
LanguagePackageManager.GRADLE: ["gradle", "build"],
|
|
140
|
+
LanguagePackageManager.GEM: ["gem", "install"],
|
|
141
|
+
LanguagePackageManager.BUNDLER: ["bundle", "install"],
|
|
142
|
+
LanguagePackageManager.GO_MOD: ["go", "mod", "download"],
|
|
143
|
+
LanguagePackageManager.COMPOSER: ["composer", "install"],
|
|
144
|
+
LanguagePackageManager.NUGET: ["nuget", "restore"],
|
|
145
|
+
LanguagePackageManager.DOTNET: ["dotnet", "restore"],
|
|
146
|
+
}
|
|
147
|
+
return commands.get(self, [])
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class ExternalPackage(BaseModel):
|
|
151
|
+
"""Represents an external package dependency with optional enrichment data."""
|
|
152
|
+
|
|
153
|
+
name: str = Field(..., description="Package name")
|
|
154
|
+
version: str | None = Field(None, description="Version specification (e.g., >=1.0.0)")
|
|
155
|
+
manager: LanguagePackageManager | None = Field(None, description="Package manager used")
|
|
156
|
+
is_dev: bool = Field(False, description="Whether this is a development dependency")
|
|
157
|
+
source: str | None = Field(None, description="Source file where this dependency was found")
|
|
158
|
+
extras: list[str] = Field(
|
|
159
|
+
default_factory=list,
|
|
160
|
+
description="Extra features requested (e.g., package[extra1,extra2])",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Extended fields for enrichment and security analysis
|
|
164
|
+
license: str | None = Field(None, description="Package license")
|
|
165
|
+
ecosystem: str | None = Field(None, description="Package ecosystem (pypi, npm, etc.)")
|
|
166
|
+
description: str | None = Field(None, description="Package description")
|
|
167
|
+
homepage: str | None = Field(None, description="Package homepage URL")
|
|
168
|
+
repository: str | None = Field(None, description="Package repository URL")
|
|
169
|
+
|
|
170
|
+
# Legacy fields for compatibility
|
|
171
|
+
current_version: str | None = Field(None, description="Currently installed version")
|
|
172
|
+
latest_version: str | None = Field(None, description="Latest available version")
|
|
173
|
+
severity: str | None = Field(None, description="Security severity if vulnerable")
|
|
174
|
+
|
|
175
|
+
model_config = ConfigDict(extra="forbid")
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
def full_spec(self) -> str:
|
|
179
|
+
"""Get the full package specification including version."""
|
|
180
|
+
spec = self.name
|
|
181
|
+
if self.extras:
|
|
182
|
+
spec = f"{spec}[{','.join(self.extras)}]"
|
|
183
|
+
if self.version:
|
|
184
|
+
spec = f"{spec}{self.version}"
|
|
185
|
+
return spec
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class SystemDependency(BaseModel):
|
|
189
|
+
"""Represents a system-level dependency required by a package."""
|
|
190
|
+
|
|
191
|
+
name: str = Field(..., description="Dependency name")
|
|
192
|
+
packages: dict[SystemPackageManager, list[str]] = Field(
|
|
193
|
+
..., description="Mapping of system package managers to their package names"
|
|
194
|
+
)
|
|
195
|
+
description: str = Field(..., description="Human-readable description")
|
|
196
|
+
required_by: list[str] = Field(
|
|
197
|
+
default_factory=list,
|
|
198
|
+
description="List of language packages that require this system dependency",
|
|
199
|
+
)
|
|
200
|
+
test_command: str | None = Field(None, description="Command to test if dependency is installed")
|
|
201
|
+
version_command: str | None = Field(None, description="Command to get installed version")
|
|
202
|
+
min_version: str | None = Field(None, description="Minimum required version")
|
|
203
|
+
|
|
204
|
+
model_config = ConfigDict(extra="forbid")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class PackageManagerCapability(BaseModel):
|
|
208
|
+
"""Describes capabilities of a package manager."""
|
|
209
|
+
|
|
210
|
+
manager: SystemPackageManager | LanguagePackageManager = Field(
|
|
211
|
+
..., description="The package manager"
|
|
212
|
+
)
|
|
213
|
+
supports_lockfile: bool = Field(False, description="Whether this manager supports lock files")
|
|
214
|
+
supports_virtual_env: bool = Field(
|
|
215
|
+
False, description="Whether this manager supports virtual environments"
|
|
216
|
+
)
|
|
217
|
+
supports_dev_dependencies: bool = Field(
|
|
218
|
+
False, description="Whether this manager distinguishes dev dependencies"
|
|
219
|
+
)
|
|
220
|
+
supports_workspaces: bool = Field(
|
|
221
|
+
False, description="Whether this manager supports workspaces/monorepos"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
model_config = ConfigDict(extra="forbid")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# Pre-defined capabilities for common package managers
|
|
228
|
+
PACKAGE_MANAGER_CAPABILITIES = {
|
|
229
|
+
LanguagePackageManager.PIP: PackageManagerCapability(
|
|
230
|
+
manager=LanguagePackageManager.PIP,
|
|
231
|
+
supports_lockfile=False,
|
|
232
|
+
supports_virtual_env=True,
|
|
233
|
+
supports_dev_dependencies=False,
|
|
234
|
+
supports_workspaces=False,
|
|
235
|
+
),
|
|
236
|
+
LanguagePackageManager.POETRY: PackageManagerCapability(
|
|
237
|
+
manager=LanguagePackageManager.POETRY,
|
|
238
|
+
supports_lockfile=True,
|
|
239
|
+
supports_virtual_env=True,
|
|
240
|
+
supports_dev_dependencies=True,
|
|
241
|
+
supports_workspaces=False,
|
|
242
|
+
),
|
|
243
|
+
LanguagePackageManager.NPM: PackageManagerCapability(
|
|
244
|
+
manager=LanguagePackageManager.NPM,
|
|
245
|
+
supports_lockfile=True,
|
|
246
|
+
supports_virtual_env=False,
|
|
247
|
+
supports_dev_dependencies=True,
|
|
248
|
+
supports_workspaces=True,
|
|
249
|
+
),
|
|
250
|
+
LanguagePackageManager.CARGO: PackageManagerCapability(
|
|
251
|
+
manager=LanguagePackageManager.CARGO,
|
|
252
|
+
supports_lockfile=True,
|
|
253
|
+
supports_virtual_env=False,
|
|
254
|
+
supports_dev_dependencies=True,
|
|
255
|
+
supports_workspaces=True,
|
|
256
|
+
),
|
|
257
|
+
}
|