alita-sdk 0.3.205__py3-none-any.whl → 0.3.206__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.
@@ -1,376 +1,354 @@
1
- import logging
2
- import traceback
3
- from typing import Type, Optional
4
-
5
- from .api_wrapper import GitLabAPIWrapper
6
- from langchain_core.tools import BaseTool, ToolException
7
- from pydantic.fields import Field
8
- from pydantic import create_model, BaseModel
9
- from gitlab.exceptions import GitlabGetError
10
-
11
- from .utils import get_diff_w_position, get_position
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
- UPDATE_FILE_PROMPT = """Updates the contents of a file in a repository. Your input MUST strictly follow these rules:
16
- Specify which file to modify passing a full file path (the path must not start with a slash); Specify at least 2 lines of the old contents which you would like to replace wrapped in OLD <<<< and >>>> OLD; Specify the new contents which you would like to replace the old contents with wrapped in NEW <<<< and >>>> NEW; NEW content may contain lines from OLD content in case you want to add content without removing the old content
17
-
18
- Example 1: Replace "old contents" to "new contents" in the file /test/test.txt from , pass in the following string:
19
-
20
- test/test.txt
21
-
22
- This is text that will not be changed
23
- OLD <<<<
24
- old contents
25
- >>>> OLD
26
- NEW <<<<
27
- new contents
28
- >>>> NEW
29
-
30
- Example 2: Extend "existing contents" with new contents" in the file /test/test.txt, pass in the following string:
31
-
32
- test/test.txt
33
-
34
- OLD <<<<
35
- existing contents
36
- >>>> OLD
37
- NEW <<<<
38
- existing contents
39
- new contents
40
- >>>> NEW"""
41
-
42
- branch_description: str = "The name of the branch required to perform corresponding action. e.g. `feature-1`. **IMPORTANT**: if branch not specified, try to determine from the chat history or clarify with user."
43
-
44
- branchInput = create_model(
45
- "BranchInput",
46
- branch_name=(str, Field(description="The name of the branch, e.g. `my_branch`.")))
47
-
48
- class CreateGitLabBranchTool(BaseTool):
49
-
50
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
51
- name: str = "create_branch"
52
- description: str = """This tool is a wrapper for the GitLab API to create a new branch in the repository."""
53
- args_schema: Type[BaseModel] = branchInput
54
-
55
- def _run(self, branch_name: str):
56
- try:
57
- logger.info(f"Creating branch {branch_name} in the repository.")
58
- return self.api_wrapper.create_branch(branch_name)
59
- except Exception as e:
60
- stacktrace = traceback.format_exc()
61
- logger.error(f"Unable to create a branch: {stacktrace}")
62
- return f"Unable to create a branch: {stacktrace}"
63
-
64
- class CreatePRTool(BaseTool):
65
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
66
- name: str = "create_pull_request"
67
- description: str = """This tool is a wrapper for the GitLab API to create a new pull request in a GitLab repository.
68
- Strictly follow and provide input parameters based on context.
69
- """
70
- args_schema: Type[BaseModel] = create_model(
71
- "CreatePRInput",
72
- pr_title=(str, Field(description="Title of pull request. Maybe generated from made changes in the branch.")),
73
- pr_body=(str, Field(description="Body or description of the pull request of made changes.")),
74
- branch=(str, Field(description=branch_description)))
75
-
76
- def _run(self, pr_title: str, pr_body: str, branch: str):
77
- try:
78
- base_branch = self.api_wrapper.branch
79
- logger.info(f"Creating pull request with title: {pr_title}, body: {pr_body}, base_branch: {base_branch}")
80
- return self.api_wrapper.create_pull_request(pr_title, pr_body, branch)
81
- except Exception as e:
82
- stacktrace = traceback.format_exc()
83
- logger.error(f"Unable to create PR: {stacktrace}")
84
- return f"Unable to create PR: {stacktrace}"
85
-
86
-
87
- class DeleteFileTool(BaseTool):
88
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
89
- name: str = "delete_file"
90
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to delete a file in a GitLab repository.
91
- Simply pass in the full file path of the file you would like to delete. **IMPORTANT**: the path must not start with a slash"""
92
- args_schema: Type[BaseModel] = create_model(
93
- "DeleteFileInput",
94
- file_path=(str, Field(description="File path of file to be deleted. e.g. `src/agents/developer/tools/git/github_tools.py`. **IMPORTANT**: the path must not start with a slash")),
95
- branch=(str, Field(description=branch_description)))
96
-
97
- def _run(self, file_path: str, branch: str):
98
- try:
99
- return self.api_wrapper.delete_file(file_path, branch)
100
- except Exception as e:
101
- stacktrace = traceback.format_exc()
102
- logger.error(f"Unable to delete file: {stacktrace}")
103
- return f"Unable to delete file: {stacktrace}"
104
-
105
- class CreateFileTool(BaseTool):
106
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
107
- name: str = "create_file"
108
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to create a file in a GitLab repository.
109
- """
110
- args_schema: Type[BaseModel] = create_model(
111
- "CreateFileInput",
112
- file_path=(str, Field(description="File path of file to be created. e.g. `src/agents/developer/tools/git/github_tools.py`. **IMPORTANT**: the path must not start with a slash")),
113
- file_contents=(str, Field(description="""
114
- Full file content to be created. It must be without any escapes, just raw content to CREATE in GIT.
115
- Generate full file content for this field without any additional texts, escapes, just raw code content.
116
- You MUST NOT ignore, skip or comment any details, PROVIDE FULL CONTENT including all content based on all best practices.
117
- """)),
118
- branch=(str, Field(description=branch_description)))
119
-
120
- def _run(self, file_path: str, file_contents: str, branch: str):
121
- logger.info(f"Create file in the repository {file_path} with content: {file_contents}")
122
- return self.api_wrapper.create_file(file_path, file_contents, branch)
123
-
124
-
125
- class SetActiveBranchTool(BaseTool):
126
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
127
- name: str = "set_active_branch"
128
- description: str = """
129
- This tool is a wrapper for the Git API and set the active branch in the repository, similar to `git checkout <branch_name>` and `git switch -c <branch_name>`."""
130
- args_schema: Type[BaseModel] = branchInput
131
-
132
- def _run(self, branch_name: str):
133
- try:
134
- logger.info(f"Set active branch {branch_name} in the repository.")
135
- return self.api_wrapper.set_active_branch(branch=branch_name)
136
- except Exception as e:
137
- stacktrace = traceback.format_exc()
138
- logger.error(f"Unable to set active branch: {stacktrace}")
139
- return f"Unable to set active branch: {stacktrace}"
140
-
141
- class ListBranchesTool(BaseTool):
142
- """Tool for interacting with the GitHub API."""
143
-
144
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
145
- name: str = "list_branches_in_repo"
146
- description: str = """This tool is a wrapper for the Git API to fetch a list of all branches in the repository.
147
- It will return the name of each branch. No input parameters are required."""
148
- args_schema: Type[BaseModel] = None
149
-
150
- def _run(self):
151
- try:
152
- logger.debug(f"List branches in the repository.")
153
- return self.api_wrapper.list_branches_in_repo()
154
- except Exception as e:
155
- stacktrace = traceback.format_exc()
156
- logger.error(f"Unable to list branches: {stacktrace}")
157
- return f"Unable to list branches: {stacktrace}"
158
-
159
-
160
- class GetPullRequesChanges(BaseTool):
161
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
162
- name: str = "get_pr_changes"
163
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to get all the changes from pull request in git diff format with added line numbers.
164
- """
165
- args_schema: Type[BaseModel] = create_model(
166
- "GetPullRequesChangesInput",
167
- pr_number=(int, Field(description="GitLab Merge Request (Pull Request) number")))
168
- handle_tool_error: bool = True
169
-
170
- def _run(self, pr_number: int):
171
- try:
172
- repo = self.api_wrapper._repo_instance
173
- try:
174
- mr = repo.mergerequests.get(pr_number)
175
- except GitlabGetError as e:
176
- if e.response_code == 404:
177
- raise ToolException(f"Merge request number {pr_number} wasn't found: {e}")
178
-
179
- res = f"""title: {mr.title}\ndescription: {mr.description}\n\n"""
180
-
181
- for change in mr.changes()["changes"]:
182
- diff_w_position = get_diff_w_position(change=change)
183
- diff = "\n".join([str(line_num) + ":" + line[1] for line_num, line in diff_w_position.items()])
184
-
185
- res = res + f"""diff --git a/{change["old_path"]} b/{change["new_path"]}\n{diff}\n"""
186
-
187
- return res
188
- except ToolException as te:
189
- raise
190
- except Exception as e:
191
- raise ToolException(f"An error occurred: {e}")
192
-
193
-
194
- class CreatePullRequestChangeCommentInput(BaseModel):
195
- pr_number: int = Field(description="""GitLab Merge Request (Pull Request) number""")
196
- file_path: str = Field(description="""File path of the changed file""")
197
- line_number: int = Field(description="""Line number from the diff for a changed file""")
198
- comment: str = Field(description="""Comment content""")
199
-
200
-
201
- class CreatePullRequestChangeComment(BaseTool):
202
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
203
- name: str = "create_pr_change_comment"
204
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to create a comment on a pull request change.
205
- """
206
- args_schema: Type[BaseModel] = CreatePullRequestChangeCommentInput
207
- handle_tool_error: bool = True
208
-
209
- def _run(self, pr_number: int, file_path: str, line_number: int, comment: str, *args):
210
- if line_number == 0:
211
- raise ToolException("Line number for comment must be greater than 0")
212
- repo = self.api_wrapper._repo_instance
213
- try:
214
- mr = repo.mergerequests.get(pr_number)
215
- except GitlabGetError as e:
216
- if e.response_code == 404:
217
- raise ToolException(f"Merge request number {pr_number} wasn't found: {e}")
218
- try:
219
- position = get_position(file_path=file_path, line_number=line_number, mr=mr)
220
-
221
- mr.discussions.create({"body": comment, "position": position})
222
- return "Comment added"
223
- except Exception as e:
224
- raise ToolException(f"An error occurred: {e}")
225
-
226
-
227
-
228
- class UpdateFileToolModel(BaseModel):
229
- file_query: str = Field(description="Strictly follow the provided rules.")
230
- branch: str = Field(description=branch_description)
231
-
232
- class AppendFileToolModel(BaseModel):
233
- file_path: str = Field(description="Path to the file new content will be appended to.")
234
- content: str = Field(description="Content to be added to the file.")
235
- branch: str = Field(description=branch_description)
236
-
237
- class ListFilesModel(BaseModel):
238
- path: Optional[str] = Field(description="Repository path/package to extract files from.", default=None)
239
- recursive: Optional[bool] = Field(description="Return files list recursively. Default: True", default=True)
240
- branch: Optional[str] = Field(description="Repository branch.", default=None)
241
-
242
- class ListFilesTool(BaseTool):
243
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
244
- name: str = "list_files"
245
- description: str = "Lists files per defined path and branch"
246
- args_schema: Type[BaseModel] = ListFilesModel
247
- handle_tool_error: bool = True
248
-
249
- def _run(self, path: str = None, recursive: bool = True, branch: str = None):
250
- try:
251
- return self.api_wrapper.list_files(path, recursive, branch)
252
- except Exception as e:
253
- stacktrace = traceback.format_exc()
254
- logger.error(f"Unable to update file: {stacktrace}")
255
- raise ToolException(f"Unable to update file: {stacktrace}")
256
-
257
- class ListFoldersModel(BaseModel):
258
- path: Optional[str] = Field(description="Repository path/package to extract folders from.", default=None)
259
- recursive: Optional[bool] = Field(description="Return folders list recursively. Default: True", default=True)
260
- branch: Optional[str] = Field(description="Repository branch.", default=None)
261
-
262
- class ListFoldersTool(BaseTool):
263
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
264
- name: str = "list_folders"
265
- description: str = "Lists folders per defined path and branch"
266
- args_schema: Type[BaseModel] = ListFoldersModel
267
- handle_tool_error: bool = True
268
-
269
- def _run(self, path: str = None, recursive: bool = True, branch: str = None):
270
- try:
271
- return self.api_wrapper.list_folders(path, recursive, branch)
272
- except Exception as e:
273
- stacktrace = traceback.format_exc()
274
- logger.error(f"Unable to extract folders: {stacktrace}")
275
- raise ToolException(f"Unable to extract folders: {stacktrace}")
276
-
277
- class UpdateFileTool(BaseTool):
278
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
279
- name: str = "update_file"
280
- description: str = UPDATE_FILE_PROMPT
281
- args_schema: Type[BaseModel] = UpdateFileToolModel
282
- handle_tool_error: bool = True
283
-
284
- def _run(self, file_query: str, branch: str):
285
- try:
286
- return self.api_wrapper.update_file(file_query, branch)
287
- except Exception as e:
288
- stacktrace = traceback.format_exc()
289
- logger.error(f"Unable to update file: {stacktrace}")
290
- raise ToolException(f"Unable to update file: {stacktrace}")
291
-
292
- class AppendFileTool(BaseTool):
293
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
294
- name: str = "append_file"
295
- description: str = """Append Tool used for adding of new content to the end of existing file.
296
- Useful in case file content is greater than model's output tokens"""
297
- args_schema: Type[BaseModel] = AppendFileToolModel
298
-
299
- def _run(self, file_path: str, content: str, branch: str):
300
- try:
301
- return self.api_wrapper.append_file(file_path, content, branch)
302
- except Exception:
303
- stacktrace = traceback.format_exc()
304
- logger.error(f"Unable to append to the file: {stacktrace}")
305
- raise ToolException(f"Unable to append to the file: {stacktrace}")
306
-
307
- class ReadFileTool(BaseTool):
308
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
309
- name: str = "read_file"
310
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to read a file in a GitLab repository.
311
- Simply pass in the full
312
- file path of the file you would like to read. **IMPORTANT**: the path must not start with a slash"""
313
- args_schema: Type[BaseModel] = create_model(
314
- "ReadFileInput",
315
- file_path=(str, Field(description="File path of file to be read. e.g. `src/agents/developer/tools/git/github_tools.py`. **IMPORTANT**: the path must not start with a slash")),
316
- branch=(str, Field(description=branch_description))
317
- )
318
-
319
- def _run(self, file_path: str, branch: str):
320
- try:
321
- return self.api_wrapper.read_file(file_path, branch)
322
- except Exception as e:
323
- stacktrace = traceback.format_exc()
324
- logger.error(f"Unable to read file: {stacktrace}")
325
- return f"Unable to read file: {stacktrace}"
326
-
327
- class GetCommitsTool(BaseTool):
328
- api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
329
- name: str = "get_commits"
330
- description: str = """This tool is a wrapper for the GitLab API, useful when you need to retrieve a list of commits from the repository."""
331
- args_schema: Type[BaseModel] = create_model(
332
- "GetCommitsInput",
333
- sha=(Optional[str],
334
- Field(description="The commit SHA to start listing commits from. If not provided, the default branch is used.",
335
- default=None)),
336
- path=(Optional[str],
337
- Field(description="The file path to filter commits by. Only commits affecting this path will be returned.",
338
- default=None)),
339
- since=(Optional[str],
340
- Field(description="Only commits after this date will be returned. Use ISO 8601 format (e.g., '2023-01-01T00:00:00Z').",
341
- default=None)),
342
- until=(Optional[str],
343
- Field(description="Only commits before this date will be returned. Use ISO 8601 format (e.g., '2023-12-31T23:59:59Z').",
344
- default=None)),
345
- author=(Optional[str],
346
- Field(description="The author of the commits. Can be a username (string)", default=None))
347
- )
348
-
349
- def _run(self, sha: Optional[str] = None,
350
- path: Optional[str] = None,
351
- since: Optional[str] = None,
352
- until: Optional[str] = None,
353
- author: Optional[str] = None):
354
- try:
355
- return self.api_wrapper.get_commits(sha, path, since, until, author)
356
- except Exception as e:
357
- stacktrace = traceback.format_exc()
358
- logger.error(f"Unable to get commits: {stacktrace}")
359
- return f"Unable to get commits: {stacktrace}"
360
-
361
- __all__ = [
362
- {"name": "create_branch", "tool": CreateGitLabBranchTool},
363
- {"name": "create_pull_request", "tool": CreatePRTool},
364
- {"name": "delete_file", "tool": DeleteFileTool},
365
- {"name": "create_file", "tool": CreateFileTool},
366
- {"name": "update_file", "tool": UpdateFileTool},
367
- {"name": "append_file", "tool": AppendFileTool},
368
- {"name": "list_files", "tool": ListFilesTool},
369
- {"name": "list_folders", "tool": ListFoldersTool},
370
- {"name": "set_active_branch", "tool": SetActiveBranchTool},
371
- {"name": "list_branches_in_repo", "tool": ListBranchesTool},
372
- {"name": "get_pr_changes", "tool": GetPullRequesChanges},
373
- {"name": "create_pr_change_comment", "tool": CreatePullRequestChangeComment},
374
- {"name": "read_file", "tool": ReadFileTool},
375
- {"name": "get_commits", "tool": GetCommitsTool}
376
- ]
1
+ # import logging
2
+ # import traceback
3
+ # from typing import Type, Optional
4
+ #
5
+ # from .api_wrapper import (
6
+ # GitLabAPIWrapper,
7
+ # CreateBranchInput,
8
+ # CreatePRInput,
9
+ # DeleteFileInput,
10
+ # CreateFileInput,
11
+ # SetActiveBranchInput,
12
+ # ReadFileInput,
13
+ # UpdateFileInput,
14
+ # AppendFileInput,
15
+ # ListFilesInput,
16
+ # ListFoldersInput,
17
+ # GetPRChangesInput,
18
+ # CreatePRChangeCommentInput,
19
+ # GetCommitsInput
20
+ # )
21
+ # from langchain_core.tools import BaseTool, ToolException
22
+ # from pydantic.fields import Field
23
+ # from pydantic import create_model, BaseModel
24
+ # from gitlab.exceptions import GitlabGetError
25
+ #
26
+ # from .utils import get_diff_w_position, get_position
27
+ #
28
+ # logger = logging.getLogger(__name__)
29
+ #
30
+ # UPDATE_FILE_PROMPT = """Updates the contents of a file in a repository. Your input MUST strictly follow these rules:
31
+ # Specify which file to modify passing a full file path (the path must not start with a slash); Specify at least 2 lines of the old contents which you would like to replace wrapped in OLD <<<< and >>>> OLD; Specify the new contents which you would like to replace the old contents with wrapped in NEW <<<< and >>>> NEW; NEW content may contain lines from OLD content in case you want to add content without removing the old content
32
+ #
33
+ # Example 1: Replace "old contents" to "new contents" in the file /test/test.txt from , pass in the following string:
34
+ #
35
+ # test/test.txt
36
+ #
37
+ # This is text that will not be changed
38
+ # OLD <<<<
39
+ # old contents
40
+ # >>>> OLD
41
+ # NEW <<<<
42
+ # new contents
43
+ # >>>> NEW
44
+ #
45
+ # Example 2: Extend "existing contents" with new contents" in the file /test/test.txt, pass in the following string:
46
+ #
47
+ # test/test.txt
48
+ #
49
+ # OLD <<<<
50
+ # existing contents
51
+ # >>>> OLD
52
+ # NEW <<<<
53
+ # existing contents
54
+ # new contents
55
+ # >>>> NEW"""
56
+ #
57
+ # branch_description: str = "The name of the branch required to perform corresponding action. e.g. `feature-1`. **IMPORTANT**: if branch not specified, try to determine from the chat history or clarify with user."
58
+ #
59
+ # branchInput = create_model(
60
+ # "BranchInput",
61
+ # branch_name=(str, Field(description="The name of the branch, e.g. `my_branch`.")))
62
+ #
63
+ # class CreateGitLabBranchTool(BaseTool):
64
+ #
65
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
66
+ # name: str = "create_branch"
67
+ # description: str = """This tool is a wrapper for the GitLab API to create a new branch in the repository."""
68
+ # args_schema: Type[BaseModel] = CreateBranchInput
69
+ #
70
+ # def _run(self, branch_name: str):
71
+ # try:
72
+ # logger.info(f"Creating branch {branch_name} in the repository.")
73
+ # return self.api_wrapper.create_branch(branch_name)
74
+ # except Exception as e:
75
+ # stacktrace = traceback.format_exc()
76
+ # logger.error(f"Unable to create a branch: {stacktrace}")
77
+ # return f"Unable to create a branch: {stacktrace}"
78
+ #
79
+ # class CreatePRTool(BaseTool):
80
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
81
+ # name: str = "create_pull_request"
82
+ # description: str = """This tool is a wrapper for the GitLab API to create a new pull request in a GitLab repository.
83
+ # Strictly follow and provide input parameters based on context.
84
+ # """
85
+ # args_schema: Type[BaseModel] = CreatePRInput
86
+ #
87
+ # def _run(self, pr_title: str, pr_body: str, branch: str):
88
+ # try:
89
+ # base_branch = self.api_wrapper.branch
90
+ # logger.info(f"Creating pull request with title: {pr_title}, body: {pr_body}, base_branch: {base_branch}")
91
+ # return self.api_wrapper.create_pull_request(pr_title, pr_body, branch)
92
+ # except Exception as e:
93
+ # stacktrace = traceback.format_exc()
94
+ # logger.error(f"Unable to create PR: {stacktrace}")
95
+ # return f"Unable to create PR: {stacktrace}"
96
+ #
97
+ #
98
+ # class DeleteFileTool(BaseTool):
99
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
100
+ # name: str = "delete_file"
101
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to delete a file in a GitLab repository.
102
+ # Simply pass in the full file path of the file you would like to delete. **IMPORTANT**: the path must not start with a slash"""
103
+ # args_schema: Type[BaseModel] = DeleteFileInput
104
+ #
105
+ # def _run(self, file_path: str, branch: str):
106
+ # try:
107
+ # return self.api_wrapper.delete_file(file_path, branch)
108
+ # except Exception as e:
109
+ # stacktrace = traceback.format_exc()
110
+ # logger.error(f"Unable to delete file: {stacktrace}")
111
+ # return f"Unable to delete file: {stacktrace}"
112
+ #
113
+ # class CreateFileTool(BaseTool):
114
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
115
+ # name: str = "create_file"
116
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to create a file in a GitLab repository.
117
+ # """
118
+ # args_schema: Type[BaseModel] = CreateFileInput
119
+ #
120
+ # def _run(self, file_path: str, file_contents: str, branch: str):
121
+ # logger.info(f"Create file in the repository {file_path} with content: {file_contents}")
122
+ # return self.api_wrapper.create_file(file_path, file_contents, branch)
123
+ #
124
+ #
125
+ # class SetActiveBranchTool(BaseTool):
126
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
127
+ # name: str = "set_active_branch"
128
+ # description: str = """
129
+ # This tool is a wrapper for the Git API and set the active branch in the repository, similar to `git checkout <branch_name>` and `git switch -c <branch_name>`."""
130
+ # args_schema: Type[BaseModel] = SetActiveBranchInput
131
+ #
132
+ # def _run(self, branch_name: str):
133
+ # try:
134
+ # logger.info(f"Set active branch {branch_name} in the repository.")
135
+ # return self.api_wrapper.set_active_branch(branch=branch_name)
136
+ # except Exception as e:
137
+ # stacktrace = traceback.format_exc()
138
+ # logger.error(f"Unable to set active branch: {stacktrace}")
139
+ # return f"Unable to set active branch: {stacktrace}"
140
+ #
141
+ # class ListBranchesTool(BaseTool):
142
+ # """Tool for interacting with the GitHub API."""
143
+ #
144
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
145
+ # name: str = "list_branches_in_repo"
146
+ # description: str = """This tool is a wrapper for the Git API to fetch a list of all branches in the repository.
147
+ # It will return the name of each branch. No input parameters are required."""
148
+ # args_schema: Type[BaseModel] = None
149
+ #
150
+ # def _run(self):
151
+ # try:
152
+ # logger.debug(f"List branches in the repository.")
153
+ # return self.api_wrapper.list_branches_in_repo()
154
+ # except Exception as e:
155
+ # stacktrace = traceback.format_exc()
156
+ # logger.error(f"Unable to list branches: {stacktrace}")
157
+ # return f"Unable to list branches: {stacktrace}"
158
+ #
159
+ #
160
+ # class GetPullRequesChanges(BaseTool):
161
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
162
+ # name: str = "get_pr_changes"
163
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to get all the changes from pull request in git diff format with added line numbers.
164
+ # """
165
+ # args_schema: Type[BaseModel] = GetPRChangesInput
166
+ # handle_tool_error: bool = True
167
+ #
168
+ # def _run(self, pr_number: int):
169
+ # try:
170
+ # repo = self.api_wrapper._repo_instance
171
+ # try:
172
+ # mr = repo.mergerequests.get(pr_number)
173
+ # except GitlabGetError as e:
174
+ # if e.response_code == 404:
175
+ # raise ToolException(f"Merge request number {pr_number} wasn't found: {e}")
176
+ #
177
+ # res = f"""title: {mr.title}\ndescription: {mr.description}\n\n"""
178
+ #
179
+ # for change in mr.changes()["changes"]:
180
+ # diff_w_position = get_diff_w_position(change=change)
181
+ # diff = "\n".join([str(line_num) + ":" + line[1] for line_num, line in diff_w_position.items()])
182
+ #
183
+ # res = res + f"""diff --git a/{change["old_path"]} b/{change["new_path"]}\n{diff}\n"""
184
+ #
185
+ # return res
186
+ # except ToolException as te:
187
+ # raise
188
+ # except Exception as e:
189
+ # raise ToolException(f"An error occurred: {e}")
190
+ #
191
+ #
192
+ # class CreatePullRequestChangeCommentInput(BaseModel):
193
+ # pr_number: int = Field(description="""GitLab Merge Request (Pull Request) number""")
194
+ # file_path: str = Field(description="""File path of the changed file""")
195
+ # line_number: int = Field(description="""Line number from the diff for a changed file""")
196
+ # comment: str = Field(description="""Comment content""")
197
+ #
198
+ #
199
+ # class CreatePullRequestChangeComment(BaseTool):
200
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
201
+ # name: str = "create_pr_change_comment"
202
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to create a comment on a pull request change.
203
+ # """
204
+ # args_schema: Type[BaseModel] = CreatePRChangeCommentInput
205
+ # handle_tool_error: bool = True
206
+ #
207
+ # def _run(self, pr_number: int, file_path: str, line_number: int, comment: str, *args):
208
+ # if line_number == 0:
209
+ # raise ToolException("Line number for comment must be greater than 0")
210
+ # repo = self.api_wrapper._repo_instance
211
+ # try:
212
+ # mr = repo.mergerequests.get(pr_number)
213
+ # except GitlabGetError as e:
214
+ # if e.response_code == 404:
215
+ # raise ToolException(f"Merge request number {pr_number} wasn't found: {e}")
216
+ # try:
217
+ # position = get_position(file_path=file_path, line_number=line_number, mr=mr)
218
+ #
219
+ # mr.discussions.create({"body": comment, "position": position})
220
+ # return "Comment added"
221
+ # except Exception as e:
222
+ # raise ToolException(f"An error occurred: {e}")
223
+ #
224
+ #
225
+ #
226
+ # class UpdateFileToolModel(BaseModel):
227
+ # file_query: str = Field(description="Strictly follow the provided rules.")
228
+ # branch: str = Field(description=branch_description)
229
+ #
230
+ # class AppendFileToolModel(BaseModel):
231
+ # file_path: str = Field(description="Path to the file new content will be appended to.")
232
+ # content: str = Field(description="Content to be added to the file.")
233
+ # branch: str = Field(description=branch_description)
234
+ #
235
+ # class ListFilesModel(BaseModel):
236
+ # path: Optional[str] = Field(description="Repository path/package to extract files from.", default=None)
237
+ # recursive: Optional[bool] = Field(description="Return files list recursively. Default: True", default=True)
238
+ # branch: Optional[str] = Field(description="Repository branch.", default=None)
239
+ #
240
+ # class ListFilesTool(BaseTool):
241
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
242
+ # name: str = "list_files"
243
+ # description: str = "Lists files per defined path and branch"
244
+ # args_schema: Type[BaseModel] = ListFilesInput
245
+ # handle_tool_error: bool = True
246
+ #
247
+ # def _run(self, path: str = None, recursive: bool = True, branch: str = None):
248
+ # try:
249
+ # return self.api_wrapper.list_files(path, recursive, branch)
250
+ # except Exception as e:
251
+ # stacktrace = traceback.format_exc()
252
+ # logger.error(f"Unable to update file: {stacktrace}")
253
+ # raise ToolException(f"Unable to update file: {stacktrace}")
254
+ #
255
+ # class ListFoldersModel(BaseModel):
256
+ # path: Optional[str] = Field(description="Repository path/package to extract folders from.", default=None)
257
+ # recursive: Optional[bool] = Field(description="Return folders list recursively. Default: True", default=True)
258
+ # branch: Optional[str] = Field(description="Repository branch.", default=None)
259
+ #
260
+ # class ListFoldersTool(BaseTool):
261
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
262
+ # name: str = "list_folders"
263
+ # description: str = "Lists folders per defined path and branch"
264
+ # args_schema: Type[BaseModel] = ListFoldersInput
265
+ # handle_tool_error: bool = True
266
+ #
267
+ # def _run(self, path: str = None, recursive: bool = True, branch: str = None):
268
+ # try:
269
+ # return self.api_wrapper.list_folders(path, recursive, branch)
270
+ # except Exception as e:
271
+ # stacktrace = traceback.format_exc()
272
+ # logger.error(f"Unable to extract folders: {stacktrace}")
273
+ # raise ToolException(f"Unable to extract folders: {stacktrace}")
274
+ #
275
+ # class UpdateFileTool(BaseTool):
276
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
277
+ # name: str = "update_file"
278
+ # description: str = UPDATE_FILE_PROMPT
279
+ # args_schema: Type[BaseModel] = UpdateFileInput
280
+ # handle_tool_error: bool = True
281
+ #
282
+ # def _run(self, file_query: str, branch: str):
283
+ # try:
284
+ # return self.api_wrapper.update_file(file_query, branch)
285
+ # except Exception as e:
286
+ # stacktrace = traceback.format_exc()
287
+ # logger.error(f"Unable to update file: {stacktrace}")
288
+ # raise ToolException(f"Unable to update file: {stacktrace}")
289
+ #
290
+ # class AppendFileTool(BaseTool):
291
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
292
+ # name: str = "append_file"
293
+ # description: str = """Append Tool used for adding of new content to the end of existing file.
294
+ # Useful in case file content is greater than model's output tokens"""
295
+ # args_schema: Type[BaseModel] = AppendFileInput
296
+ #
297
+ # def _run(self, file_path: str, content: str, branch: str):
298
+ # try:
299
+ # return self.api_wrapper.append_file(file_path, content, branch)
300
+ # except Exception:
301
+ # stacktrace = traceback.format_exc()
302
+ # logger.error(f"Unable to append to the file: {stacktrace}")
303
+ # raise ToolException(f"Unable to append to the file: {stacktrace}")
304
+ #
305
+ # class ReadFileTool(BaseTool):
306
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
307
+ # name: str = "read_file"
308
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to read a file in a GitLab repository.
309
+ # Simply pass in the full
310
+ # file path of the file you would like to read. **IMPORTANT**: the path must not start with a slash"""
311
+ # args_schema: Type[BaseModel] = ReadFileInput
312
+ #
313
+ # def _run(self, file_path: str, branch: str):
314
+ # try:
315
+ # return self.api_wrapper.read_file(file_path, branch)
316
+ # except Exception as e:
317
+ # stacktrace = traceback.format_exc()
318
+ # logger.error(f"Unable to read file: {stacktrace}")
319
+ # return f"Unable to read file: {stacktrace}"
320
+ #
321
+ # class GetCommitsTool(BaseTool):
322
+ # api_wrapper: GitLabAPIWrapper = Field(default_factory=GitLabAPIWrapper)
323
+ # name: str = "get_commits"
324
+ # description: str = """This tool is a wrapper for the GitLab API, useful when you need to retrieve a list of commits from the repository."""
325
+ # args_schema: Type[BaseModel] = GetCommitsInput
326
+ #
327
+ # def _run(self, sha: Optional[str] = None,
328
+ # path: Optional[str] = None,
329
+ # since: Optional[str] = None,
330
+ # until: Optional[str] = None,
331
+ # author: Optional[str] = None):
332
+ # try:
333
+ # return self.api_wrapper.get_commits(sha, path, since, until, author)
334
+ # except Exception as e:
335
+ # stacktrace = traceback.format_exc()
336
+ # logger.error(f"Unable to get commits: {stacktrace}")
337
+ # return f"Unable to get commits: {stacktrace}"
338
+ #
339
+ # __all__ = [
340
+ # {"name": "create_branch", "tool": CreateGitLabBranchTool},
341
+ # {"name": "create_pull_request", "tool": CreatePRTool},
342
+ # {"name": "delete_file", "tool": DeleteFileTool},
343
+ # {"name": "create_file", "tool": CreateFileTool},
344
+ # {"name": "update_file", "tool": UpdateFileTool},
345
+ # {"name": "append_file", "tool": AppendFileTool},
346
+ # {"name": "list_files", "tool": ListFilesTool},
347
+ # {"name": "list_folders", "tool": ListFoldersTool},
348
+ # {"name": "set_active_branch", "tool": SetActiveBranchTool},
349
+ # {"name": "list_branches_in_repo", "tool": ListBranchesTool},
350
+ # {"name": "get_pr_changes", "tool": GetPullRequesChanges},
351
+ # {"name": "create_pr_change_comment", "tool": CreatePullRequestChangeComment},
352
+ # {"name": "read_file", "tool": ReadFileTool},
353
+ # {"name": "get_commits", "tool": GetCommitsTool}
354
+ # ]