import os
import urllib.parse
import gitlab
from langchain.agents import Tool
class GitLabAgent:
def __init__(self):
self.gl = gitlab.Gitlab(os.getenv("GITLAB_URL"),
private_token=os.getenv("GITLAB_TOKEN"))
# Projects
def get_project(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
return f"Project: {project.name}\nPath: {project.path_with_namespace}\
nDescription: {project.description}\nVisibility: {project.visibility}"
except Exception as e:
return f"Error getting project: {str(e)}"
def list_projects(self, search=""):
try:
projects = self.gl.projects.list(search=search, get_all=True)
result = "Projects:\n"
for p in projects:
result += f"- {p.path_with_namespace}\n"
return result
except Exception as e:
return f"Error listing projects: {str(e)}"
def create_project(self, name, description=""):
try:
project = self.gl.projects.create({'name': name, 'description':
description})
return f"Created project: {project.path_with_namespace}"
except Exception as e:
return f"Error creating project: {str(e)}"
# Groups
def get_group(self, group_path):
try:
group = self.gl.groups.get(urllib.parse.quote(group_path, safe=''))
return f"Group: {group.name}\nPath: {group.full_path}\nDescription:
{group.description}"
except Exception as e:
return f"Error getting group: {str(e)}"
def list_groups(self, search=""):
try:
groups = self.gl.groups.list(search=search, get_all=True)
result = "Groups:\n"
for g in groups:
result += f"- {g.full_path}\n"
return result
except Exception as e:
return f"Error listing groups: {str(e)}"
# Users
def get_user(self, username):
try:
users = self.gl.users.list(username=username)
if not users:
return f"User '{username}' not found"
user = users[0]
return f"User: {user.name} (@{user.username})\nEmail: {user.email}\
nState: {user.state}"
except Exception as e:
return f"Error getting user: {str(e)}"
def list_users(self, search=""):
try:
users = self.gl.users.list(search=search, get_all=True)
result = "Users:\n"
for u in users:
result += f"- {u.name} (@{u.username})\n"
return result
except Exception as e:
return f"Error listing users: {str(e)}"
# Issues
def get_project_issues(self, project_path, state="opened"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
issues = project.issues.list(state=state, pget_all=True)
result = f"{state.title()} issues in {project.path_with_namespace}:\n"
for issue in issues:
result += f"- #{issue.iid}: {issue.title}\n"
return result
except Exception as e:
return f"Error getting issues: {str(e)}"
def create_issue(self, project_path, title, description=""):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
issue = project.issues.create({'title': title, 'description':
description})
return f"Created issue #{issue.iid}: {issue.title}"
except Exception as e:
return f"Error creating issue: {str(e)}"
# Merge Requests
def get_merge_requests(self, project_path, state="opened"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
mrs = project.mergerequests.list(state=state, pget_all=True)
result = f"{state.title()} merge requests in
{project.path_with_namespace}:\n"
for mr in mrs:
result += f"- !{mr.iid}: {mr.title} ({mr.source_branch} ->
{mr.target_branch})\n"
return result
except Exception as e:
return f"Error getting merge requests: {str(e)}"
def create_merge_request(self, project_path, source_branch, target_branch,
title, description=""):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
mr = project.mergerequests.create({
'source_branch': source_branch,
'target_branch': target_branch,
'title': title,
'description': description
})
return f"Created MR !{mr.iid}: {mr.title}"
except Exception as e:
return f"Error creating merge request: {str(e)}"
# Branches
def get_branches(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
branches = project.branches.list(get_all=True)
result = f"Branches in {project.path_with_namespace}:\n"
for branch in branches:
result += f"- {branch.name}\n"
return result
except Exception as e:
return f"Error getting branches: {str(e)}"
def create_branch(self, project_path, branch_name, ref="main"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
branch = project.branches.create({'branch': branch_name, 'ref': ref})
return f"Created branch: {branch.name}"
except Exception as e:
return f"Error creating branch: {str(e)}"
# Commits
def get_commits(self, project_path, ref_name="main", limit=10):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
commits = project.commits.list(ref_name=ref_name, per_page=limit)
result = f"Recent commits in {project.path_with_namespace}
({ref_name}):\n"
for commit in commits:
result += f"- {commit.short_id}: {commit.title}\n"
return result
except Exception as e:
return f"Error getting commits: {str(e)}"
# Tags
def get_tags(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
tags = project.tags.list(get_all=True)
result = f"Tags in {project.path_with_namespace}:\n"
for tag in tags:
result += f"- {tag.name}\n"
return result
except Exception as e:
return f"Error getting tags: {str(e)}"
def create_tag(self, project_path, tag_name, ref, message=""):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
tag = project.tags.create({'tag_name': tag_name, 'ref': ref, 'message':
message})
return f"Created tag: {tag.name}"
except Exception as e:
return f"Error creating tag: {str(e)}"
# Pipelines
def get_pipelines(self, project_path, limit=10):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
pipelines = project.pipelines.list(per_page=limit)
result = f"Recent pipelines in {project.path_with_namespace}:\n"
for pipeline in pipelines:
result += f"- #{pipeline.id}: {pipeline.status} ({pipeline.ref})\n"
return result
except Exception as e:
return f"Error getting pipelines: {str(e)}"
def trigger_pipeline(self, project_path, ref="main"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
pipeline = project.pipelines.create({'ref': ref})
return f"Triggered pipeline #{pipeline.id} on {ref}"
except Exception as e:
return f"Error triggering pipeline: {str(e)}"
# Jobs
def get_jobs(self, project_path, pipeline_id):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
pipeline = project.pipelines.get(pipeline_id)
jobs = pipeline.jobs.list()
result = f"Jobs in pipeline #{pipeline_id}:\n"
for job in jobs:
result += f"- {job.name}: {job.status}\n"
return result
except Exception as e:
return f"Error getting jobs: {str(e)}"
# Releases
def get_releases(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
releases = project.releases.list(pget_all=True)
result = f"Releases in {project.path_with_namespace}:\n"
for release in releases:
result += f"- {release.tag_name}: {release.name}\n"
return result
except Exception as e:
return f"Error getting releases: {str(e)}"
# Milestones
def get_milestones(self, project_path, state="active"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
milestones = project.milestones.list(state=state)
result = f"{state.title()} milestones in
{project.path_with_namespace}:\n"
for milestone in milestones:
result += f"- {milestone.title}\n"
return result
except Exception as e:
return f"Error getting milestones: {str(e)}"
# Wikis
def get_wiki_pages(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
wikis = project.wikis.list()
result = f"Wiki pages in {project.path_with_namespace}:\n"
for wiki in wikis:
result += f"- {wiki.title}\n"
return result
except Exception as e:
return f"Error getting wiki pages: {str(e)}"
# Snippets
def get_snippets(self, project_path):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
snippets = project.snippets.list()
result = f"Snippets in {project.path_with_namespace}:\n"
for snippet in snippets:
result += f"- {snippet.title}\n"
return result
except Exception as e:
return f"Error getting snippets: {str(e)}"
# Repository Files
def get_file_content(self, project_path, file_path, ref="main"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
file = project.files.get(file_path=file_path, ref=ref)
return f"File: {file_path}\nContent:\n{file.decode().decode('utf-8')
[:500]}..."
except Exception as e:
return f"Error getting file: {str(e)}"
def list_repository_tree(self, project_path, path="", ref="main"):
try:
project = self.gl.projects.get(urllib.parse.quote(project_path,
safe=''))
items = project.repository_tree(path=path, ref=ref)
result = f"Repository tree in {project.path_with_namespace} ({path or
'root'}):\n"
for item in items:
result += f"- {item['name']} ({item['type']})\n"
return result
except Exception as e:
return f"Error listing repository tree: {str(e)}"
def get_tools(self):
return [
Tool(name="GetProject", func=self.get_project, description="Get project
info. Input: project_path"),
Tool(name="ListProjects", func=self.list_projects, description="List
projects. Input: search_term"),
Tool(name="CreateProject", func=self.create_project,
description="Create project. Input: name"),
Tool(name="GetGroup", func=self.get_group, description="Get group info.
Input: group_path"),
Tool(name="ListGroups", func=self.list_groups, description="List
groups. Input: search_term"),
Tool(name="GetUser", func=self.get_user, description="Get user info.
Input: username"),
Tool(name="ListUsers", func=self.list_users, description="List users.
Input: search_term"),
Tool(name="GetIssues", func=self.get_project_issues, description="Get
project issues. Input: project_path"),
Tool(name="CreateIssue", func=self.create_issue, description="Create
issue. Input: project_path|title|description"),
Tool(name="GetMergeRequests", func=self.get_merge_requests,
description="Get merge requests. Input: project_path"),
Tool(name="CreateMergeRequest", func=self.create_merge_request,
description="Create MR. Input: project_path|source|target|title"),
Tool(name="GetBranches", func=self.get_branches, description="Get
branches. Input: project_path"),
Tool(name="CreateBranch", func=self.create_branch, description="Create
branch. Input: project_path|branch_name|ref"),
Tool(name="GetCommits", func=self.get_commits, description="Get
commits. Input: project_path"),
Tool(name="GetTags", func=self.get_tags, description="Get tags. Input:
project_path"),
Tool(name="CreateTag", func=self.create_tag, description="Create tag.
Input: project_path|tag_name|ref"),
Tool(name="GetPipelines", func=self.get_pipelines, description="Get
pipelines. Input: project_path"),
Tool(name="TriggerPipeline", func=self.trigger_pipeline,
description="Trigger pipeline. Input: project_path|ref"),
Tool(name="GetJobs", func=self.get_jobs, description="Get pipeline
jobs. Input: project_path|pipeline_id"),
Tool(name="GetReleases", func=self.get_releases, description="Get
releases. Input: project_path"),
Tool(name="GetMilestones", func=self.get_milestones, description="Get
milestones. Input: project_path"),
Tool(name="GetWikiPages", func=self.get_wiki_pages, description="Get
wiki pages. Input: project_path"),
Tool(name="GetSnippets", func=self.get_snippets, description="Get
snippets. Input: project_path"),
Tool(name="GetFileContent", func=self.get_file_content,
description="Get file content. Input: project_path|file_path"),
Tool(name="ListRepositoryTree", func=self.list_repository_tree,
description="List repository tree. Input: project_path")
]