Skip to content

Commit 57f4df4

Browse files
authored
Adding suggest bool flag to suggest type changes to an issue (#2548)
1 parent 1add5fe commit 57f4df4

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

pkg/github/__toolsnaps__/update_issue_type.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"description": "Update the type of an existing issue (e.g. 'bug', 'feature').",
88
"inputSchema": {
99
"properties": {
10+
"is_suggestion": {
11+
"description": "If true, propose the issue type change instead of applying it. Defaults to false, which applies the change to the issue.",
12+
"type": "boolean"
13+
},
1014
"issue_number": {
1115
"description": "The issue number to update",
1216
"minimum": 1,

pkg/github/granular_tools_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package github
22

33
import (
44
"context"
5+
"encoding/json"
56
"net/http"
67
"strings"
78
"testing"
@@ -458,6 +459,70 @@ func TestGranularUpdateIssueType(t *testing.T) {
458459
}
459460
}
460461

462+
func TestGranularUpdateIssueTypeSuggest(t *testing.T) {
463+
tests := []struct {
464+
name string
465+
requestArgs map[string]any
466+
expected map[string]any
467+
}{
468+
{
469+
name: "suggest without rationale",
470+
requestArgs: map[string]any{
471+
"owner": "owner",
472+
"repo": "repo",
473+
"issue_number": float64(1),
474+
"issue_type": "bug",
475+
"suggest": true,
476+
},
477+
expected: map[string]any{
478+
"owner": "owner",
479+
"repo": "repo",
480+
"issue_number": float64(1),
481+
"issue_type": "bug",
482+
"suggested": true,
483+
},
484+
},
485+
{
486+
name: "suggest with rationale",
487+
requestArgs: map[string]any{
488+
"owner": "owner",
489+
"repo": "repo",
490+
"issue_number": float64(1),
491+
"issue_type": "feature",
492+
"rationale": " Asks for dark mode support ",
493+
"suggest": true,
494+
},
495+
expected: map[string]any{
496+
"owner": "owner",
497+
"repo": "repo",
498+
"issue_number": float64(1),
499+
"issue_type": "feature",
500+
"rationale": "Asks for dark mode support",
501+
"suggested": true,
502+
},
503+
},
504+
}
505+
506+
for _, tc := range tests {
507+
t.Run(tc.name, func(t *testing.T) {
508+
// No HTTP handler registered: any API call would fail the test.
509+
deps := BaseDeps{Client: mustNewGHClient(t, MockHTTPClientWithHandlers(nil))}
510+
serverTool := GranularUpdateIssueType(translations.NullTranslationHelper)
511+
handler := serverTool.Handler(deps)
512+
513+
request := createMCPRequest(tc.requestArgs)
514+
result, err := handler(ContextWithDeps(context.Background(), deps), &request)
515+
require.NoError(t, err)
516+
require.False(t, result.IsError)
517+
518+
textContent := getTextResult(t, result)
519+
var got map[string]any
520+
require.NoError(t, json.Unmarshal([]byte(textContent.Text), &got))
521+
assert.Equal(t, tc.expected, got)
522+
})
523+
}
524+
}
525+
461526
func TestGranularUpdateIssueTypeInvalidRationale(t *testing.T) {
462527
tests := []struct {
463528
name string

pkg/github/issues_granular.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,11 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser
512512
"State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature).",
513513
MaxLength: jsonschema.Ptr(280),
514514
},
515+
"is_suggestion": {
516+
Type: "boolean",
517+
Description: "If true, propose the issue type change instead of applying it. " +
518+
"Defaults to false, which applies the change to the issue.",
519+
},
515520
},
516521
Required: []string{"owner", "repo", "issue_number", "issue_type"},
517522
},
@@ -542,6 +547,28 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser
542547
if len([]rune(rationale)) > 280 {
543548
return utils.NewToolResultError("parameter rationale must be 280 characters or less"), nil, nil
544549
}
550+
suggest, err := OptionalParam[bool](args, "suggest")
551+
if err != nil {
552+
return utils.NewToolResultError(err.Error()), nil, nil
553+
}
554+
555+
if suggest {
556+
suggestion := map[string]any{
557+
"owner": owner,
558+
"repo": repo,
559+
"issue_number": issueNumber,
560+
"issue_type": issueType,
561+
"suggested": true,
562+
}
563+
if rationale != "" {
564+
suggestion["rationale"] = rationale
565+
}
566+
r, err := json.Marshal(suggestion)
567+
if err != nil {
568+
return utils.NewToolResultErrorFromErr("failed to marshal suggestion", err), nil, nil
569+
}
570+
return utils.NewToolResultText(string(r)), nil, nil
571+
}
545572

546573
client, err := deps.GetClient(ctx)
547574
if err != nil {

0 commit comments

Comments
 (0)