Conversation
Adds support for defining sub-agents inline within a workflow markdown file. A special separator line `<!-- @agent: name -->` marks the start of each sub-agent's frontmatter + prompt block. During compilation: - Sub-agent sections are extracted from the markdown body - The main workflow uses only the content before the first separator - Each sub-agent is written to .github/agents/<name>.md The separator: - Is an HTML comment (hidden in rendered markdown) - Uses @agent: prefix that is very unlikely to occur naturally - Name must start with a letter (alphanumeric, hyphens, underscores only) - Duplicate names within the same file produce a compile error Files changed: - pkg/parser/sub_agent_extractor.go: new ExtractInlineSubAgents() function - pkg/parser/sub_agent_extractor_test.go: comprehensive parser tests - pkg/workflow/compiler_types.go: InlineSubAgents field on WorkflowData - pkg/workflow/compiler_orchestrator_tools.go: extraction in processToolsAndMarkdown - pkg/workflow/compiler_orchestrator_workflow.go: pass rawMainMarkdown to extractAdditionalConfigurations - pkg/workflow/workflow_builder.go: populate InlineSubAgents on WorkflowData - pkg/workflow/compiler.go: writeInlineSubAgentFiles() and resolveAgentsDir() - pkg/workflow/compiler_inline_sub_agents_test.go: end-to-end compilation tests Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b4ccf8aa-3004-4c65-b20c-bc4daf8621fb Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…b/agents/ Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b4ccf8aa-3004-4c65-b20c-bc4daf8621fb Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…ection doc comment Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b4ccf8aa-3004-4c65-b20c-bc4daf8621fb Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot the marker should be visible and render nicely in preview mode, do not use xml comments |
… heading The <!-- @agent: name --> separator was replaced with ## @agent: name (a level-2 Markdown heading). This format renders visibly and nicely in any Markdown preview (GitHub, VS Code, etc.) while remaining clearly distinguishable from regular document headings thanks to the @agent: prefix. H1 and H3 headings are not treated as separators — only ## is recognized. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/c8ebe799-71f2-43c9-8bcf-979101db0816 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Changed to Example rendering on GitHub: # Handle issue
Triage the issue and delegate work.
## @agent: planner
---
engine: copilot
---
You are a planning specialist.The Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
<!-- @agent: name --> separator## @agent: name separator
|
@copilot do not use syntax @ it has a special meaning in github. |
The @ character has special meaning on GitHub (mentions). Changed the separator from ## @agent: name to ## agent: name — still a visible level-2 Markdown heading, still clearly distinguishable as a keyword, but without the @ that triggers GitHub's mention system. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/d4d3b72b-97f8-4338-94ba-6d783e3e26b1 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Removed the # Triage issue
Analyze the issue and delegate to sub-agents.
## agent: planner
---
engine: copilot
---
You are a planning specialist.Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
## @agent: name separator## agent: name separator
|
@copilot you need a marker to optional finish the agent, in case it gets inserted around. |
Add an optional ## end: name end marker as the closing counterpart to ## agent: name. When present, it explicitly terminates the agent block, preventing any content inserted after it from being captured as part of the agent's body. Behaviour: - ## end: name closes the currently open agent when the name matches - A mismatched name or no open agent: line is treated as plain text - Without an end marker behaviour is unchanged (next ## agent: / EOF) Also adds subAgentEndRegex, agentMarker/markerKind types, rewrites the event-driven parser loop, and adds 5 new unit tests covering end-marker scenarios. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/66bfdc33-4155-4758-91f5-38c7cac0c51a Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Added in 6fc89fc. The optional ## agent: planner
---
engine: copilot
---
You are a planning specialist.
## end: planner
Any content here is outside the agent block.
## agent: executor
---
engine: copilot
---
You are an executor.
## end: executorBehaviour:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
## agent: name separator## agent: name / ## end: name delimiters
|
@copilot the parsing and writing of agents must happen in JavaScript after inline the runtimeimports |
Instead of writing .github/agents/<name>.md files at Go compile time,
the extraction and file writing now happens in JavaScript at runtime
(interpolate_prompt.cjs Step 1.5), AFTER {{#runtime-import}} macros
have been fully inlined. This ensures any imports inside an agent block
are resolved before the agent file is written.
Go side (compile time):
- ExtractInlineSubAgents() is still called to strip agent sections from
the effective markdown used for include expansion, name extraction,
and safe-outputs scanning — syntax errors (duplicate names) are still
caught at compile time.
- Removed writeInlineSubAgentFiles(), resolveAgentsDir(), and the
InlineSubAgents field; the Go compiler no longer writes agent files.
- Deleted compiler_inline_sub_agents_test.go.
JavaScript side (runtime):
- New extract_inline_sub_agents.cjs with extractInlineSubAgents() and
writeInlineSubAgents() functions (20 tests).
- interpolate_prompt.cjs now calls writeInlineSubAgents() in a new
Step 1.5, immediately after processRuntimeImports() completes.
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/8459f895-82d7-4680-8593-6e91d2ed60bc
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in 41ad346. The extraction and writing of agent files now happens in JavaScript at runtime, inside New file:
The Go compiler still calls Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
Smoke Test Run 25249938003 — Results Core Tests (1–12): ✅✅✅✅✅✅✅✅✅✅✅✅ Overall: PARTIAL (test 19 skipped — no safe test PR to close; all other tests passed)
|
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/13245a33-a1a2-4a4a-87a1-1557e7605e2a Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal! This is an automated review from the Claude smoke test agent (Run 25249938003). The inline sub-agent syntax implementation looks well-structured.
💥 [THE END] — Illustrated by Smoke Claude · ● 352.7K
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| "gh-aw": patch | |||
There was a problem hiding this comment.
🤖 Smoke test review comment #1 — The changeset correctly targets the gh-aw package with a patch bump. This is appropriate for an additive, backward-compatible feature. Run 25249938003.
| "gh-aw": patch | ||
| --- | ||
|
|
||
| Add inline sub-agent syntax using `## agent: \`name\`` H2 headings in workflow markdown. |
There was a problem hiding this comment.
🤖 Smoke test review comment #2 — Good, the changeset description accurately captures the feature: inline sub-agent syntax with H2 boundary delimiters. Run 25249938003.
Done in 938a6ad. JS ( Shell restore step (
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
Show the first 3000 charsprint(logs[:3000])` (http block)
|
|
@copilot the agent front matter supports the following fields:
no other fields for now |
…only Agent-Logs-Url: https://github.com/github/gh-aw/sessions/5fb3231a-5e0d-4a20-a07d-9a3d9cc30ebe Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
| with: | ||
| name: activation | ||
| path: /tmp/gh-aw | ||
| - name: Restore inline sub-agents from activation artifact |
There was a problem hiding this comment.
@copilot should happen after "restoring agent config folders from base branch"
step and move all the code logic into a shell script file
There was a problem hiding this comment.
Done in 9a6b03b. The restore step now runs after "Restore agent config folders from base branch", and the logic has been moved to actions/setup/sh/restore_inline_sub_agents.sh. The step passes GH_AW_SUB_AGENT_DIR and GH_AW_SUB_AGENT_EXT env vars to the script rather than embedding the values inline.
|
@copilot add features.inline-agents to guard enable the code generation of steps for this feature. Only enable for smoke-copilot |
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/5fb3231a-5e0d-4a20-a07d-9a3d9cc30ebe Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in a999662. Sub-agent frontmatter is now restricted to |
|
@copilot create a file at |
…ranch restore, use shell script - Add InlineAgentsFeatureFlag constant to pkg/constants/feature_constants.go - Create actions/setup/sh/restore_inline_sub_agents.sh to encapsulate restore logic - Add pkg/workflow/sub_agent_step.go with generateRestoreInlineSubAgentsStep helper - Move "Restore inline sub-agents" step to after "Restore agent config folders from base branch" - Guard activation artifact upload and restore step with features.inline-agents flag - Enable features.inline-agents only in smoke-copilot.md - Update golden test files and recompile all lock files Agent-Logs-Url: https://github.com/github/gh-aw/sessions/506d4917-baf6-4194-928d-3f43599a759e Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in 9a6b03b. Added Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/56f6fd95-9918-4756-a664-655da00757d0 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in 1775dca. Created
|
Implements inline sub-agent definitions directly inside workflow markdown files, with per-engine file placement, correct cross-job delivery to the agent runner, and reference documentation for the feature.
Changes Made
Inline Sub-Agent Syntax
## agent: \name`` level-2 headings directly in the workflow markdown filea-z,0-9,_,-##heading or EOF — no explicit end marker neededenginefield; they run within the parent workflow's enginedescriptionandmodel(default:"inherited") — any other fields are stripped at runtime with a warningfeatures.inline-agentsFeature Flagfeatures.inline-agentsflag in the workflow frontmatterfeatures:\n inline-agents: trueget the upload and restore steps compiled insmoke-copilot.mdas the canonical test workflowExperimental Compilation Warning
compiler_orchestrator_tools.go: detects inline sub-agents during compilation and emits an experimental-feature warning (⚠ Using experimental feature: inline-sub-agents), following the same pattern asrate-limit,dispatch_repository, andmerge-pull-requestPer-Engine Sub-Agent Placement
Each engine writes sub-agent files to the directory and with the filename extension it natively expects:
.claude/agents/.md.codex/agents/.md.gemini/agents/.md.agents/agents/.agent.mdpkg/parser/sub_agent_extractor.go: newGetEngineSubAgentDir()andGetEngineSubAgentExt()helpersextract_inline_sub_agents.cjs:getEngineSubAgentTarget(engineId)maps engine ID →{ dir, ext }interpolate_prompt.cjs: readsGH_AW_ENGINE_IDenv var and forwards it towriteInlineSubAgentspkg/workflow/template.go: emitsGH_AW_ENGINE_IDin the interpolation step env (known at compile time)Frontmatter Field Enforcement
extract_inline_sub_agents.cjs: newfilterSubAgentFrontmatter()function strips any frontmatter field that is notdescriptionormodelbefore writing the agent file, emitting a runtime warning for each stripped fieldmodeldefaults to"inherited"(agent uses the parent workflow's model) when not specifiedRuntime Extraction & Cross-Job Delivery
actions/setup/js/extract_inline_sub_agents.cjsextracts sub-agent blocks after{{#runtime-import}}macros are resolvedwriteInlineSubAgentsaccepts an optionalagentsBaseDirparameter; in production this is set to/tmp/gh-awso agents land under/tmp/gh-aw/<engine-dir>/actions/setup/sh/restore_inline_sub_agents.sh, which runs after "Restore agent config folders from base branch"Feature Documentation
.github/aw/subagents.mdexplaining the inline sub-agents syntax, thefeatures.inline-agentsopt-in flag, per-engine placement, MCP guidance (works best with CLI proxy and GH proxy enabled since sub-agents do not have MCPs), and when this pattern is most useful — particularly for running tasks concurrently with smaller models and then aggregating results with a larger top-level model