Class: DSPy::Tools::GitHubCLIToolset

Inherits:
Toolset
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dspy/tools/github_cli_toolset.rb

Overview

GitHub CLI toolset for common GitHub operations

Instance Method Summary collapse

Methods inherited from Toolset

schema_for_method, to_tools, tool, toolset_name

Constructor Details

#initializeGitHubCLIToolset

Returns a new instance of GitHubCLIToolset.



73
74
75
# File 'lib/dspy/tools/github_cli_toolset.rb', line 73

def initialize
  # No persistent state needed
end

Instance Method Details

#api_request(endpoint:, method: 'GET', fields: {}, repo: nil) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/dspy/tools/github_cli_toolset.rb', line 193

def api_request(endpoint:, method: 'GET', fields: {}, repo: nil)
  # Restrict to read-only operations
  unless method.upcase == 'GET'
    return "Error: Only GET requests are allowed for read-only access"
  end
  
  cmd = build_gh_command(['api', endpoint])
  cmd << ['--method', method.upcase]
  
  fields.each do |key, value|
    cmd << ['-f', "#{key}=#{shell_escape(value)}"]
  end
  
  if repo
    cmd << ['--repo', shell_escape(repo)]
  end

  result = execute_command(cmd.flatten.join(' '))
  
  if result[:success]
    result[:output]
  else
    "API request failed: #{result[:error]}"
  end
rescue StandardError => e
  "Error making API request: #{e.message}"
end

#get_issue(issue_number:, repo: nil) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/dspy/tools/github_cli_toolset.rb', line 148

def get_issue(issue_number:, repo: nil)
  cmd = build_gh_command(['issue', 'view', issue_number.to_s, '--json', 'number,title,state,body,labels,assignees,url'])
  
  if repo
    cmd << ['--repo', shell_escape(repo)]
  end

  result = execute_command(cmd.flatten.join(' '))
  
  if result[:success]
    parse_issue_details(result[:output])
  else
    "Failed to get issue: #{result[:error]}"
  end
rescue StandardError => e
  "Error getting issue: #{e.message}"
end

#get_pr(pr_number:, repo: nil) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/dspy/tools/github_cli_toolset.rb', line 167

def get_pr(pr_number:, repo: nil)
  cmd = build_gh_command(['pr', 'view', pr_number.to_s, '--json', 'number,title,state,body,baseRefName,headRefName,mergeable,url'])
  
  if repo
    cmd << ['--repo', shell_escape(repo)]
  end

  result = execute_command(cmd.flatten.join(' '))
  
  if result[:success]
    parse_pr_details(result[:output])
  else
    "Failed to get pull request: #{result[:error]}"
  end
rescue StandardError => e
  "Error getting pull request: #{e.message}"
end

#list_issues(state: IssueState::Open, labels: [], assignee: nil, repo: nil, limit: 20) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/dspy/tools/github_cli_toolset.rb', line 86

def list_issues(state: IssueState::Open, labels: [], assignee: nil, repo: nil, limit: 20)
  cmd = build_gh_command(['issue', 'list', '--json', 'number,title,state,labels,assignees,url'])
  cmd << ['--state', state.serialize]
  cmd << ['--limit', limit.to_s]
  
  labels.each { |label| cmd << ['--label', shell_escape(label)] }
  
  if assignee
    cmd << ['--assignee', shell_escape(assignee)]
  end
  
  if repo
    cmd << ['--repo', shell_escape(repo)]
  end

  result = execute_command(cmd.flatten.join(' '))
  
  if result[:success]
    parse_issue_list(result[:output])
  else
    "Failed to list issues: #{result[:error]}"
  end
rescue StandardError => e
  "Error listing issues: #{e.message}"
end

#list_prs(state: PRState::Open, author: nil, base: nil, repo: nil, limit: 20) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/dspy/tools/github_cli_toolset.rb', line 119

def list_prs(state: PRState::Open, author: nil, base: nil, repo: nil, limit: 20)
  cmd = build_gh_command(['pr', 'list', '--json', 'number,title,state,baseRefName,headRefName,url'])
  cmd << ['--state', state.serialize]
  cmd << ['--limit', limit.to_s]
  
  if author
    cmd << ['--author', shell_escape(author)]
  end
  
  if base
    cmd << ['--base', shell_escape(base)]
  end
  
  if repo
    cmd << ['--repo', shell_escape(repo)]
  end

  result = execute_command(cmd.flatten.join(' '))
  
  if result[:success]
    parse_pr_list(result[:output])
  else
    "Failed to list pull requests: #{result[:error]}"
  end
rescue StandardError => e
  "Error listing pull requests: #{e.message}"
end

#traffic_clones(repo:, per: nil) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/dspy/tools/github_cli_toolset.rb', line 239

def traffic_clones(repo:, per: nil)
  endpoint = "repos/#{repo}/traffic/clones"
  cmd = build_gh_command(['api', shell_escape(endpoint)])
  cmd << ['-f', "per=#{shell_escape(per)}"] if per

  result = execute_command(cmd.flatten.join(' '))

  if result[:success]
    parse_traffic(result[:output], label: 'Clones')
  else
    "Failed to fetch traffic clones: #{result[:error]}"
  end
rescue StandardError => e
  "Error fetching traffic clones: #{e.message}"
end

#traffic_views(repo:, per: nil) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/dspy/tools/github_cli_toolset.rb', line 222

def traffic_views(repo:, per: nil)
  endpoint = "repos/#{repo}/traffic/views"
  cmd = build_gh_command(['api', shell_escape(endpoint)])
  cmd << ['-f', "per=#{shell_escape(per)}"] if per

  result = execute_command(cmd.flatten.join(' '))

  if result[:success]
    parse_traffic(result[:output], label: 'Views')
  else
    "Failed to fetch traffic views: #{result[:error]}"
  end
rescue StandardError => e
  "Error fetching traffic views: #{e.message}"
end