Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5074,6 +5074,11 @@
"additionalProperties": true
}
]
},
"normalize-closing-keywords": {
"type": "boolean",
"description": "When true, strip backticks from recognized issue-closing keywords (e.g. `Closes #1` \u2192 Closes #1) in body fields for this output type.",
"examples": [true, false]
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -6400,6 +6405,11 @@
"additionalProperties": true
}
]
},
"normalize-closing-keywords": {
"type": "boolean",
"description": "When true, strip backticks from recognized issue-closing keywords (e.g. `Closes #1` \u2192 Closes #1) in body fields for this output type.",
"examples": [true, false]
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -6796,6 +6806,11 @@
"description": "When true, adds workflows: write to the GitHub App token permissions. Required when allowed-files targets .github/workflows/ paths. Requires safe-outputs.github-app to be configured because the workflows permission is a GitHub App-only permission and cannot be granted via GITHUB_TOKEN.",
"default": false,
"examples": [true, false]
},
"normalize-closing-keywords": {
"type": "boolean",
"description": "When true, strip backticks from recognized issue-closing keywords (e.g. `Closes #1` \u2192 Closes #1) in body fields for this output type.",
"examples": [true, false]
}
},
"additionalProperties": false,
Expand Down
9 changes: 9 additions & 0 deletions pkg/workflow/tool_description_enhancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func enhanceToolDescription(toolName, baseDescription string, safeOutputs *SafeO
if config.RequireTemporaryID {
constraints = append(constraints, "temporary_id is required.")
}
if config.NormalizeClosingKeywords != nil && *config.NormalizeClosingKeywords {
constraints = append(constraints, "Backtick-wrapped issue-closing keyword references (e.g. `Closes #1`) in the body field will be automatically normalized to plain text.")
}
}

case "set_issue_field":
Expand Down Expand Up @@ -217,6 +220,9 @@ func enhanceToolDescription(toolName, baseDescription string, safeOutputs *SafeO
if config.TargetRepoSlug != "" {
constraints = append(constraints, fmt.Sprintf("Comments will be added in repository %q.", config.TargetRepoSlug))
}
if config.NormalizeClosingKeywords != nil && *config.NormalizeClosingKeywords {
constraints = append(constraints, "Backtick-wrapped issue-closing keyword references (e.g. `Closes #1`) in the body field will be automatically normalized to plain text.")
}
}
constraints = append(constraints, "Supports reply_to_id for discussion threading.")

Expand Down Expand Up @@ -247,6 +253,9 @@ func enhanceToolDescription(toolName, baseDescription string, safeOutputs *SafeO
if config.RequireTemporaryID {
constraints = append(constraints, "temporary_id is required.")
}
if config.NormalizeClosingKeywords != nil && *config.NormalizeClosingKeywords {
constraints = append(constraints, "Backtick-wrapped issue-closing keyword references (e.g. `Closes #1`) in the body field will be automatically normalized to plain text.")
}
}

case "create_pull_request_review_comment":
Expand Down
66 changes: 66 additions & 0 deletions pkg/workflow/tool_description_enhancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,69 @@ func TestEnhanceToolDescriptionSubmitPullRequestReviewTargetRepo(t *testing.T) {
t.Fatalf("expected target repo constraint in description, got: %s", description)
}
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsCreateIssue(t *testing.T) {
description := enhanceToolDescription("create_issue", "Create an issue.", &SafeOutputsConfig{
CreateIssues: &CreateIssuesConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(true)},
},
})
if !strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("expected normalize-closing-keywords note in description, got: %s", description)
}
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsFalseCreateIssue(t *testing.T) {
description := enhanceToolDescription("create_issue", "Create an issue.", &SafeOutputsConfig{
CreateIssues: &CreateIssuesConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(false)},
},
})
if strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("did not expect normalize-closing-keywords note when disabled, got: %s", description)
}
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsAddComment(t *testing.T) {
description := enhanceToolDescription("add_comment", "Add a comment.", &SafeOutputsConfig{
AddComments: &AddCommentsConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(true)},
},
})
if !strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("expected normalize-closing-keywords note in description, got: %s", description)
}
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsFalseAddComment(t *testing.T) {
description := enhanceToolDescription("add_comment", "Add a comment.", &SafeOutputsConfig{
AddComments: &AddCommentsConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(false)},
},
})
if strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("did not expect normalize-closing-keywords note when disabled, got: %s", description)
}
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsCreatePullRequest(t *testing.T) {
description := enhanceToolDescription("create_pull_request", "Create a pull request.", &SafeOutputsConfig{
CreatePullRequests: &CreatePullRequestsConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(true)},
},
})
if !strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("expected normalize-closing-keywords note in description, got: %s", description)
}
Comment on lines +228 to +258
}

func TestEnhanceToolDescriptionNormalizeClosingKeywordsFalseCreatePullRequest(t *testing.T) {
description := enhanceToolDescription("create_pull_request", "Create a pull request.", &SafeOutputsConfig{
CreatePullRequests: &CreatePullRequestsConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{NormalizeClosingKeywords: boolPtr(false)},
},
})
if strings.Contains(description, "Backtick-wrapped issue-closing keyword references") {
t.Fatalf("did not expect normalize-closing-keywords note when disabled, got: %s", description)
}
}
Loading