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
5 changes: 5 additions & 0 deletions .changeset/minor-imports-based-agent-files.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 16 additions & 12 deletions .github/instructions/custom-agents.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ Custom agent files can be placed in several locations, each serving a different
- **Use case**: Task-specific agents (documentation, testing, refactoring)

### 4. agentic workflow integration
- **Location**: Specified in workflow frontmatter via `engine.custom-agent` field
- **Pattern**: Any markdown file path relative to repository root
- **Location**: Imported via `imports` field in workflow frontmatter
- **Pattern**: Any markdown files under `.github/agents/` directory
- **Scope**: Custom agent for specific agentic workflow execution
- **Use case**: Workflow-specific agent configuration
- **Important**: Only one agent file is allowed per workflow

## File Format

Expand Down Expand Up @@ -366,7 +367,7 @@ You are an experienced code reviewer focused on code quality, security, and best

## Integration with gh-aw

The gh-aw (GitHub Agentic Workflows) tool supports custom agent files through the `engine.custom-agent` field in workflow frontmatter.
The gh-aw (GitHub Agentic Workflows) tool supports custom agent files through the `imports` field in workflow frontmatter. Any markdown files under the `.github/agents/` directory are treated as custom agent files when imported.

### Configuration

Expand All @@ -375,7 +376,8 @@ The gh-aw (GitHub Agentic Workflows) tool supports custom agent files through th
on: issues
engine:
id: copilot
custom-agent: .github/agents/my-agent.md
imports:
- .github/agents/my-agent.md
---

# My Workflow
Expand All @@ -393,10 +395,11 @@ Custom agent files are supported by the following engines:

### File Path Resolution

- Paths are relative to the repository root
- Must point to an existing markdown file
- Agent files are imported via the `imports` field
- Must be markdown files located under `.github/agents/` directory
- Only one agent file is allowed per workflow
- File is validated during workflow compilation
- Checkout step is automatically added if custom agent is specified
- Checkout step is automatically added if agent file is imported

### Example Workflow with Custom Agent

Expand All @@ -410,7 +413,8 @@ permissions:
issues: write
engine:
id: copilot
custom-agent: .github/agents/issue-triager.md
imports:
- .github/agents/issue-triager.md
tools:
github:
allowed:
Expand Down Expand Up @@ -505,10 +509,10 @@ tools: [editFiles, createFile, search, codeSearch]
- Ensure `applyTo` is only used in `.instructions.md` files

### Custom Agent File Not Found
- Verify file path is relative to repository root
- Ensure file exists and is committed
- Check file extension is `.md`
- Confirm path in `engine.custom-agent` is correct
- Verify agent file is imported in the `imports` field
- Ensure file exists and is committed under `.github/agents/` directory
- Confirm agent file path is correct in imports list
- Remember: only one agent file is allowed per workflow

## References

Expand Down
123 changes: 121 additions & 2 deletions .github/workflows/technical-doc-writer.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/technical-doc-writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ permissions: read-all

engine:
id: copilot
custom-agent: technical-doc-writer.md

network:
allowed:
Expand All @@ -20,6 +19,7 @@ network:

imports:
- ../instructions/documentation.instructions.md
- ../agents/technical-doc-writer.md

safe-outputs:
add-comment:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unbloat-docs.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 5 additions & 8 deletions docs/src/content/docs/reference/frontmatter-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ source: "example-value"

# Optional array of workflow specifications to import (similar to @include
# directives but defined in frontmatter). Format: owner/repo/path@ref (e.g.,
# githubnext/agentics/workflows/shared/common.md@v1.0.0).
# githubnext/agentics/workflows/shared/common.md@v1.0.0). Markdown files under
# .github/agents/ directory are treated as custom agent files (only one agent
# file allowed per workflow).
# (optional)
imports: []
# Array of Workflow specification in format owner/repo/path@ref
# Array of Workflow specification in format owner/repo/path@ref. Markdown
# files under .github/agents/ are treated as agent configuration files.

# Workflow triggers that define when the agentic workflow should run. Supports
# standard GitHub Actions trigger events plus special command triggers for
Expand Down Expand Up @@ -934,12 +937,6 @@ engine:
args: []
# Array of strings

# Optional path to a custom agent configuration file. For copilot engine, this is
# passed as --agent flag. For claude and codex engines, the markdown body from the
# agent file is injected as a system prompt.
# (optional)
custom-agent: "example-value"

# MCP server definitions
# (optional)
mcp-servers:
Expand Down
35 changes: 35 additions & 0 deletions pkg/parser/frontmatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type ImportsResult struct {
MergedNetwork string // Merged network configuration from all imports
MergedPermissions string // Merged permissions configuration from all imports
ImportedFiles []string // List of imported file paths (for manifest)
AgentFile string // Path to custom agent file (if imported)
}

// ExtractFrontmatterFromContent parses YAML frontmatter from markdown content string
Expand Down Expand Up @@ -411,6 +412,7 @@ func ProcessImportsFromFrontmatterWithManifest(frontmatter map[string]any, baseD
var engines []string
var safeOutputs []string
var processedFiles []string
var agentFile string // Track custom agent file

for _, importPath := range imports {
// Handle section references (file.md#Section)
Expand Down Expand Up @@ -440,6 +442,38 @@ func ProcessImportsFromFrontmatterWithManifest(frontmatter map[string]any, baseD
// Add to list of processed files (use original importPath for manifest)
processedFiles = append(processedFiles, importPath)

// Check if this is a custom agent file (any markdown file under .github/agents)
isAgentFile := strings.Contains(fullPath, "/.github/agents/") && strings.HasSuffix(strings.ToLower(fullPath), ".md")
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The agent file detection logic may fail for Windows paths or paths that don't use Unix-style separators. Consider using filepath.Separator or strings.Contains(filepath.ToSlash(fullPath), \"/.github/agents/\") for cross-platform compatibility.

Suggested change
isAgentFile := strings.Contains(fullPath, "/.github/agents/") && strings.HasSuffix(strings.ToLower(fullPath), ".md")
isAgentFile := strings.Contains(filepath.ToSlash(fullPath), "/.github/agents/") && strings.HasSuffix(strings.ToLower(fullPath), ".md")

Copilot uses AI. Check for mistakes.
if isAgentFile {
if agentFile != "" {
// Multiple agent files found - error
return nil, fmt.Errorf("multiple agent files found in imports: '%s' and '%s'. Only one agent file is allowed per workflow", agentFile, importPath)
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message uses importPath but should use fullPath for consistency with how agentFile is set on line 452. This could show incorrect path information in the error message.

Suggested change
return nil, fmt.Errorf("multiple agent files found in imports: '%s' and '%s'. Only one agent file is allowed per workflow", agentFile, importPath)
return nil, fmt.Errorf("multiple agent files found in imports: '%s' and '%s'. Only one agent file is allowed per workflow", agentFile, fullPath)

Copilot uses AI. Check for mistakes.
}
agentFile = fullPath
log.Printf("Found agent file: %s", fullPath)

// For agent files, only extract markdown content
// Extract markdown content from imported file
markdownContent, err := processIncludedFileWithVisited(fullPath, sectionName, false, visited)
if err != nil {
return nil, fmt.Errorf("failed to process markdown from agent file '%s': %w", fullPath, err)
}
if markdownContent != "" {
markdownBuilder.WriteString(markdownContent)
// Add blank line separator between imported files
if !strings.HasSuffix(markdownContent, "\n\n") {
if strings.HasSuffix(markdownContent, "\n") {
markdownBuilder.WriteString("\n")
} else {
markdownBuilder.WriteString("\n\n")
}
}
}

// Skip other extractions for agent files
continue
}

// Extract tools from imported file
toolsContent, err := processIncludedFileWithVisited(fullPath, sectionName, true, visited)
if err != nil {
Expand Down Expand Up @@ -530,6 +564,7 @@ func ProcessImportsFromFrontmatterWithManifest(frontmatter map[string]any, baseD
MergedNetwork: networkBuilder.String(),
MergedPermissions: permissionsBuilder.String(),
ImportedFiles: processedFiles,
AgentFile: agentFile,
}, nil
}

Expand Down
11 changes: 4 additions & 7 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
},
"imports": {
"type": "array",
"description": "Optional array of workflow specifications to import (similar to @include directives but defined in frontmatter). Format: owner/repo/path@ref (e.g., githubnext/agentics/workflows/shared/common.md@v1.0.0).",
"description": "Optional array of workflow specifications to import (similar to @include directives but defined in frontmatter). Format: owner/repo/path@ref (e.g., githubnext/agentics/workflows/shared/common.md@v1.0.0). Any markdown files under .github/agents directory are treated as custom agent files and only one agent file is allowed per workflow.",
"items": {
"type": "string",
"description": "Workflow specification in format owner/repo/path@ref"
"description": "Workflow specification in format owner/repo/path@ref. Markdown files under .github/agents/ are treated as agent configuration files."
},
"examples": [
["shared/jqschema.md", "shared/reporting.md"],
["shared/mcp/gh-aw.md", "shared/jqschema.md", "shared/reporting.md"],
["../instructions/documentation.instructions.md"]
["../instructions/documentation.instructions.md"],
[".github/agents/my-agent.md"]
]
},
"on": {
Expand Down Expand Up @@ -3171,10 +3172,6 @@
"type": "string"
},
"description": "Optional array of command-line arguments to pass to the AI engine CLI. These arguments are injected after all other args but before the prompt."
},
"custom-agent": {
"type": "string",
"description": "Optional path to a custom agent configuration file. For copilot engine, this is passed as --agent flag. For claude and codex engines, the markdown body from the agent file is injected as a system prompt."
}
},
"required": ["id"],
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/.github/aw/actions-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
"sha": "2028fbc5c25fe9cf00d9f06a71cc4710d4507903"
}
}
}
}
Loading
Loading