akseljoonas HF Staff commited on
Commit
1d719d4
·
1 Parent(s): 0b8bdf3

list repos tool working

Browse files
Files changed (1) hide show
  1. agent/tools/github_list_repos.py +42 -17
agent/tools/github_list_repos.py CHANGED
@@ -17,10 +17,10 @@ def list_repos(
17
  owner_type: Literal["user", "org"] = "org",
18
  sort: Literal["stars", "forks", "updated", "created"] = "stars",
19
  order: Literal["asc", "desc"] = "desc",
20
- limit: Optional[int] = None,
21
  ) -> ToolResult:
22
  """
23
- List repositories for a user or organization using GitHub Search API.
24
 
25
  Args:
26
  owner: GitHub username or organization name
@@ -41,8 +41,10 @@ def list_repos(
41
  "isError": True,
42
  }
43
 
44
- # Build search query
45
- query = f"org:{owner}" if owner_type == "org" else f"user:{owner}"
 
 
46
 
47
  headers = {
48
  "Accept": "application/vnd.github+json",
@@ -52,20 +54,35 @@ def list_repos(
52
 
53
  all_repos = []
54
  page = 1
55
- per_page = min(100, limit) if limit else 100
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  try:
58
  while True:
59
  params = {
60
- "q": query,
61
- "sort": sort,
62
- "order": order,
63
  "page": page,
64
  "per_page": per_page,
65
  }
66
 
 
 
 
 
 
67
  response = requests.get(
68
- "https://api.github.com/search/repositories",
69
  headers=headers,
70
  params=params,
71
  timeout=30,
@@ -95,8 +112,7 @@ def list_repos(
95
  "isError": True,
96
  }
97
 
98
- data = response.json()
99
- items = data.get("items", [])
100
 
101
  if not items:
102
  break
@@ -114,16 +130,16 @@ def list_repos(
114
  "open_issues": item.get("open_issues_count", 0),
115
  "topics": item.get("topics", []),
116
  "updated_at": item.get("updated_at"),
 
117
  }
118
  )
119
 
120
- # Check limits
121
- if limit and len(all_repos) >= limit:
122
- all_repos = all_repos[:limit]
123
  break
124
 
125
- total_count = data.get("total_count", 0)
126
- if len(all_repos) >= total_count or page * per_page >= 1000:
127
  break
128
 
129
  page += 1
@@ -136,6 +152,15 @@ def list_repos(
136
  "isError": True,
137
  }
138
 
 
 
 
 
 
 
 
 
 
139
  if not all_repos:
140
  return {
141
  "formatted": f"No repositories found for {owner_type} '{owner}'",
@@ -217,7 +242,7 @@ GITHUB_LIST_REPOS_TOOL_SPEC = {
217
  },
218
  "limit": {
219
  "type": "integer",
220
- "description": "Maximum number of repositories to return. No limit if not specified.",
221
  },
222
  },
223
  "required": ["owner"],
 
17
  owner_type: Literal["user", "org"] = "org",
18
  sort: Literal["stars", "forks", "updated", "created"] = "stars",
19
  order: Literal["asc", "desc"] = "desc",
20
+ limit: Optional[int] = 30,
21
  ) -> ToolResult:
22
  """
23
+ List repositories for a user or organization using GitHub REST API.
24
 
25
  Args:
26
  owner: GitHub username or organization name
 
41
  "isError": True,
42
  }
43
 
44
+ if owner_type == "org":
45
+ url = f"https://api.github.com/orgs/{owner}/repos"
46
+ else:
47
+ url = f"https://api.github.com/users/{owner}/repos"
48
 
49
  headers = {
50
  "Accept": "application/vnd.github+json",
 
54
 
55
  all_repos = []
56
  page = 1
57
+ per_page = 100 # Maximum allowed by GitHub
58
+
59
+ # Map our sort values to GitHub API sort values
60
+ # Note: GitHub list repos API doesn't support sorting by stars/forks
61
+ # We'll fetch all repos and sort in memory for those cases
62
+ api_sort_map = {
63
+ "created": "created",
64
+ "updated": "updated",
65
+ "stars": None, # Not supported by list API
66
+ "forks": None, # Not supported by list API
67
+ }
68
+
69
+ api_sort = api_sort_map.get(sort)
70
+ need_manual_sort = api_sort is None
71
 
72
  try:
73
  while True:
74
  params = {
 
 
 
75
  "page": page,
76
  "per_page": per_page,
77
  }
78
 
79
+ # Only add sort/direction if API supports it
80
+ if api_sort:
81
+ params["sort"] = api_sort
82
+ params["direction"] = order
83
+
84
  response = requests.get(
85
+ url,
86
  headers=headers,
87
  params=params,
88
  timeout=30,
 
112
  "isError": True,
113
  }
114
 
115
+ items = response.json()
 
116
 
117
  if not items:
118
  break
 
130
  "open_issues": item.get("open_issues_count", 0),
131
  "topics": item.get("topics", []),
132
  "updated_at": item.get("updated_at"),
133
+ "created_at": item.get("created_at"),
134
  }
135
  )
136
 
137
+ # Check if we got fewer results than requested (last page)
138
+ if len(items) < per_page:
 
139
  break
140
 
141
+ # Stop if we have enough repos
142
+ if limit and len(all_repos) >= limit:
143
  break
144
 
145
  page += 1
 
152
  "isError": True,
153
  }
154
 
155
+ # Manual sorting if needed (for stars/forks)
156
+ if need_manual_sort and all_repos:
157
+ reverse = order == "desc"
158
+ all_repos.sort(key=lambda x: x[sort], reverse=reverse)
159
+
160
+ # Apply limit after sorting
161
+ if limit:
162
+ all_repos = all_repos[:limit]
163
+
164
  if not all_repos:
165
  return {
166
  "formatted": f"No repositories found for {owner_type} '{owner}'",
 
242
  },
243
  "limit": {
244
  "type": "integer",
245
+ "description": "Maximum number of repositories to return. No limit if not specified. Default: 30.",
246
  },
247
  },
248
  "required": ["owner"],