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
4 changes: 4 additions & 0 deletions docs/src/content/docs/agent-factory-status.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| [Example: Properly Provisioned Permissions](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/example-permissions-warning.md) | copilot | [![Example: Properly Provisioned Permissions](https://github.com/githubnext/gh-aw/actions/workflows/example-permissions-warning.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/example-permissions-warning.lock.yml) | - | - |
| [Firewall Test Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/firewall.md) | copilot | [![Firewall Test Agent](https://github.com/githubnext/gh-aw/actions/workflows/firewall.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/firewall.lock.yml) | - | - |
<<<<<<< HEAD
| [Functional Pragmatist](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-pragmatist.md) | copilot | [![Functional Pragmatist](https://github.com/githubnext/gh-aw/actions/workflows/functional-pragmatist.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-pragmatist.lock.yml) | `0 9 * * 2,4` | - |
=======
<<<<<<< HEAD
| [Functional Enhancer](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-enhancer.md) | claude | [![Functional Enhancer](https://github.com/githubnext/gh-aw/actions/workflows/functional-enhancer.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-enhancer.lock.yml) | `0 9 * * 2,4` | - |
=======
| [Functional Pragmatist](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-programming-enhancer.md) | claude | [![Functional Pragmatist](https://github.com/githubnext/gh-aw/actions/workflows/functional-programming-enhancer.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-programming-enhancer.lock.yml) | `0 9 * * 2,4` | - |
>>>>>>> ba904f257b69bfcc9738b01ca4c61995b23506a4
>>>>>>> origin/main
| [GitHub MCP Remote Server Tools Report Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-mcp-tools-report.md) | claude | [![GitHub MCP Remote Server Tools Report Generator](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-tools-report.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-tools-report.lock.yml) | - | - |
| [GitHub MCP Structural Analysis](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-mcp-structural-analysis.md) | claude | [![GitHub MCP Structural Analysis](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-structural-analysis.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-structural-analysis.lock.yml) | `0 11 * * 1-5` | - |
| [GitHub Remote MCP Authentication Test](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-remote-mcp-auth-test.md) | copilot | [![GitHub Remote MCP Authentication Test](https://github.com/githubnext/gh-aw/actions/workflows/github-remote-mcp-auth-test.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-remote-mcp-auth-test.lock.yml) | - | - |
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/data/action_pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"version": "v5.6.0",
"sha": "a26af69be951a213d495a4c3e4e4022e16d87065"
},
"actions/upload-artifact@v4": {
"actions/upload-artifact@v4.6.2": {
"repo": "actions/upload-artifact",
"version": "v4.6.2",
"sha": "ea165f8d65b6e75b540449e92b4886f43607fa02"
Expand Down
54 changes: 54 additions & 0 deletions pkg/workflow/prompts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,60 @@ func TestSafeOutputsPromptText_FollowsXMLFormat(t *testing.T) {
t.Skip("Safe outputs prompt is now generated dynamically based on enabled tools")
}

func TestSafeOutputsPrompt_NeverListsToolNames(t *testing.T) {
// CRITICAL: This test ensures tool names are NEVER listed in the safe outputs prompt.
// The agent must query the MCP server to discover available tools - listing them
// directly causes the agent to try accessing them before MCP setup is complete.
compiler := &Compiler{}
var yaml strings.Builder

// Create a config with multiple safe outputs enabled
safeOutputs := &SafeOutputsConfig{
CreateIssues: &CreateIssuesConfig{},
AddComments: &AddCommentsConfig{},
CreateDiscussions: &CreateDiscussionsConfig{},
UpdateIssues: &UpdateIssuesConfig{},
}

data := &WorkflowData{
ParsedTools: NewTools(map[string]any{}),
SafeOutputs: safeOutputs,
}

compiler.generateUnifiedPromptStep(&yaml, data)
output := yaml.String()

// Verify safe outputs section exists
if !strings.Contains(output, "<safe-outputs>") {
t.Fatal("Expected safe outputs section in generated prompt")
}

// CRITICAL: Ensure tool names are NEVER listed in the prompt
forbiddenToolNames := []string{
"create_issue",
"add_comment",
"create_discussion",
"update_issue",
"update_pull_request",
"close_issue",
"close_pull_request",
"create_pull_request",
"add_labels",
"remove_labels",
}

for _, toolName := range forbiddenToolNames {
if strings.Contains(output, toolName) {
t.Errorf("CRITICAL: Safe outputs prompt must NOT list tool name %q. Agent should discover tools via MCP server query.", toolName)
}
}

// Verify the correct instruction is present
if !strings.Contains(output, "Discover available tools from the safeoutputs MCP server") {
t.Error("Expected prompt to instruct agent to query MCP server for tools")
}
}

// ============================================================================
// Cache Memory Prompt Tests
// ============================================================================
Expand Down
6 changes: 4 additions & 2 deletions pkg/workflow/safe_outputs_config_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ func HasSafeOutputsEnabled(safeOutputs *SafeOutputsConfig) bool {
return enabled
}

// GetEnabledSafeOutputToolNames returns a list of enabled safe output tool names
// that can be used in the prompt to inform the agent which tools are available
// GetEnabledSafeOutputToolNames returns a list of enabled safe output tool names.
// NOTE: Tool names should NOT be included in agent prompts. The agent should query
// the MCP server to discover available tools. This function is used for generating
// the tools.json file that the MCP server provides, and for diagnostic logging.
func GetEnabledSafeOutputToolNames(safeOutputs *SafeOutputsConfig) []string {
tools := getEnabledSafeOutputToolNamesReflection(safeOutputs)

Expand Down
15 changes: 6 additions & 9 deletions pkg/workflow/unified_prompt_step.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,8 @@ func (c *Compiler) collectPromptSections(data *WorkflowData) []PromptSection {

// 7. Safe outputs instructions (if enabled)
if HasSafeOutputsEnabled(data.SafeOutputs) {
enabledTools := GetEnabledSafeOutputToolNames(data.SafeOutputs)
if len(enabledTools) > 0 {
unifiedPromptLog.Printf("Adding safe outputs section: tools=%d", len(enabledTools))
safeOutputsContent := `<safe-outputs>
unifiedPromptLog.Print("Adding safe outputs section")
safeOutputsContent := `<safe-outputs>
<description>GitHub API Access Instructions</description>
<important>
The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations.
Expand All @@ -290,11 +288,10 @@ Discover available tools from the safeoutputs MCP server.
**Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed.
</instructions>
</safe-outputs>`
sections = append(sections, PromptSection{
Content: safeOutputsContent,
IsFile: false,
})
}
sections = append(sections, PromptSection{
Content: safeOutputsContent,
IsFile: false,
})
}

// 8. GitHub context (if GitHub tool is enabled)
Expand Down
Loading