Skip to content

Custom agents and skills packaging

Custom agents and skills packaging

This document explains how custom agents and skills are packaged, discovered, loaded, enabled/disabled, and surfaced in the extracted Copilot CLI app.js bundle. Existing docs cover prompts and task orchestration broadly; this document focuses on the packaging surfaces: AGENTS.md, SKILL.md, skill directories, plugin contributions, remote/custom-agent sources, and session events such as session.skills_loaded and session.custom_agents_updated.

The important implementation point is that “customization” is multi-layered:

  • instruction files such as AGENTS.md influence prompt/context;
  • SKILL.md files define reusable skills and sometimes slash-command-like invocations;
  • custom agent markdown/config files define specialized agents with prompts, tools, models, MCP servers, and skills;
  • plugins can contribute both skills and agents;
  • remote/project/inherited sources can merge into a session.

Because app.js is bundled/minified, symbol names are unstable. Line references below are searchable anchors in the extracted bundle and will shift across releases.

Source anchors

AreaAnchor strings / minified symbolsApprox. app.js lineWhat it shows
Instruction filesAGENTS.md, Nested AGENTS.md, Child instruction files499Repo/cwd/inherited instruction files are discovered and folded into prompt context.
Skill filesSKILL.md, skillsParseSkillMarkdown, allowedTools, userInvocable, disableModelInvocation525Skills are parsed from markdown files and normalized into runtime metadata.
Skill settingsskillDirectories, disabledSkills239, 4471Settings can add skill search roots and disable named skills.
Skill eventssession.skills_loaded, enableSkill, disableSkill, emitSkillsChanged4361, 4396, 4471Loaded/enabled skill metadata is emitted to clients and updated dynamically.
Custom-agent settingscustomAgents:{defaultLocalOnly}, customAgentsLocalOnly239, 4471Settings/runtime options control custom-agent discovery scope.
Agent eventssession.custom_agents_updated, emitCustomAgentsUpdated4361, 4475Session emits agent metadata, warnings, and errors after load/merge.
Provided agentsprovidedCustomAgents, mergeProvidedCustomAgents4471, 4475Agents passed by the host are merged with discovered agents and de-duplicated.
Remote agentsagents/swe/custom-agents, include_sources=org,enterprise2789Remote custom agents can be loaded from GitHub service endpoints.
Plugin agentssource:{type:"plugin", pluginName, marketplaceName, filePath}2789Plugins can package custom-agent definitions.
Agent executioncustomAgents, disableModelInvocation, executeAgent, Unknown agent type3735, 4043Agent names become callable subagent/custom-agent types when model invocation is enabled.

Packaging map

flowchart TD
Repo[Repository] --> AgentsMd[AGENTS.md]
Repo --> SkillsDir[SKILL.md files]
User[User config] --> SkillDirectories[skillDirectories]
Plugins[Installed plugins] --> PluginSkills[plugin skills]
Plugins --> PluginAgents[plugin agents]
Remote[Remote org/enterprise/project service] --> RemoteAgents[remote custom agents]
Host[Embedding host] --> ProvidedAgents[providedCustomAgents]
AgentsMd --> Prompt[Prompt/context assembly]
SkillsDir --> SkillsLoaded[session.skills_loaded]
PluginSkills --> SkillsLoaded
SkillDirectories --> SkillsLoaded
PluginAgents --> AgentsUpdated[session.custom_agents_updated]
RemoteAgents --> AgentsUpdated
ProvidedAgents --> AgentsUpdated
AgentsUpdated --> AgentTools[custom-agent/subagent tool choices]

Instruction files versus skills versus agents

The bundle distinguishes three related concepts:

ConceptFile/sourceRuntime role
InstructionsAGENTS.md, .github/copilot-instructions.md, nested/child instruction filesAdd prompt context and rules.
SkillsSKILL.md or command markdownAdd reusable capability descriptions, optional allowed tools, and optional user-invocable commands.
Custom agentsAgent markdown/config from user/project/plugin/remote/provided sourcesAdd specialized subagent personas with prompts, tools, models, MCP servers, and skills.

This distinction matters because disabling a skill does not remove a custom agent, and instruction files are prompt context rather than callable tools.

AGENTS.md discovery

The instruction-discovery path looks for model/instruction files including:

  • copilot-instructions.md under .github;
  • AGENTS.md in repository or working-directory locations;
  • CLAUDE.md and GEMINI.md compatibility files;
  • nested AGENTS.md;
  • child instruction files when enabled.

The bundle labels discovered content with source/location metadata such as repository, working directory, nested agents, and child instructions. These entries feed prompt assembly rather than the session.custom_agents_updated event.

Skill discovery

Skills are loaded from multiple roots:

  • configured skillDirectories;
  • plugin-contributed skill directories;
  • built-in/default skill locations;
  • markdown command files that can be parsed as user-invocable skills/commands.

The loader checks each directory for a direct SKILL.md or for child directories containing SKILL.md. It deduplicates by real path and skill name, collects warnings/errors, and returns normalized skill metadata.

Skill metadata

A parsed skill includes fields such as:

FieldMeaning
nameUnique skill identifier.
descriptionHuman-readable description.
sourceSource type such as project, personal, plugin, etc.
filePathPath to the SKILL.md definition when available.
baseDirDirectory containing the skill.
allowedToolsOptional tools auto-approved/allowed while the skill is active.
contentFull skill markdown content injected when invoked.
userInvocableWhether users can invoke the skill directly.
disableModelInvocationWhether the model should not invoke it as an agent/tool capability.
pluginName / pluginVersionPlugin provenance when contributed by a plugin.

skill.invoked events include name, path, content, allowed tools, and plugin provenance, showing that skill content can be injected into the conversation when used.

Skill enable/disable lifecycle

The settings schema includes disabledSkills. At runtime:

Method/APIBehavior
enableSkill(name)Removes the name from disabledSkills, persists/config-refreshes, and emits updated skill metadata.
disableSkill(name)Adds the name to disabledSkills, persists/config-refreshes, and emits updated skill metadata.
emitSkillsChanged()Emits session.skills_loaded with enabled flags derived from disabledSkills.
Skill reload APIClears caches, reloads skills, and returns load diagnostics.

The session.skills_loaded event includes each skill’s name, description, source, user-invocable flag, enabled flag, and path.

Custom-agent sources

Custom agents can originate from several places:

SourceEvidence / behavior
Host-provided agentsprovidedCustomAgents are set from runtime options and merged before emitting updates.
User/project discoveryDiscovery respects config discovery and local-only settings.
PluginsPlugin agent files parse into agents with plugin provenance.
Remote serviceEndpoint path like agents/swe/custom-agents/<owner>/<repo> can return project/org/enterprise agents.
Inherited/remote metadataEvent schema allows source values such as user, project, inherited, remote, and plugin.

When no auth info or provider is available, the bundle skips remote/custom-agent loading and emits only provided agents.

Custom-agent metadata

The session.custom_agents_updated schema emits agents with:

FieldMeaning
idStable identifier, falling back to name.
nameInternal name.
displayNameHuman-readable display name.
descriptionDescription shown to users/model prompts.
sourceSource location: user, project, inherited, remote, or plugin.
toolsAllowed/requested tools, nullable.
userInvocableWhether a user can directly choose/invoke the agent.
modelOptional default model for the agent.
warnings / errorsLoad diagnostics for UI/debugging.

The merge logic de-duplicates agents by normalized id or name, preserving host-provided agents first.

Plugin-packaged agents

Plugin agent parsing can produce agents with:

  • name and displayName;
  • description;
  • tools or default *;
  • prompt loader;
  • mcpServers;
  • model;
  • disableModelInvocation;
  • userInvocable;
  • source:{ type:"plugin", pluginName, marketplaceName, filePath };
  • skills.

This is why plugin-extension-architecture.md and this document overlap: plugins are a packaging vehicle, while custom agents/skills are runtime capabilities contributed by that vehicle.

Agent execution integration

During tool/prompt construction, available custom agents are merged with built-in agent types. The runtime filters out agents with disableModelInvocation:true when building model-invocable agent lists.

Agent dispatch maps a requested agent name to:

  • built-in general-purpose agent path;
  • built-in specialized agent path;
  • custom agent executor path;
  • error if the agent type is unknown.

Custom agents can also select or override models, including inherited auto-mode behavior from the parent session.

/env visibility

The environment/status command path lists loaded components. Evidence shows output sections for:

  • MCP servers;
  • skills;
  • custom agents;
  • plugins.

For skills it includes source and path. For custom agents it lists display names. This is the main user-facing inventory for verifying whether packaging/discovery succeeded.

End-to-end load flow

sequenceDiagram
participant Session
participant Settings
participant Plugins
participant Remote
participant UI
Session->>Settings: read skillDirectories / disabledSkills / customAgents config
Session->>Plugins: collect plugin skill and agent sources
Session->>Session: parse SKILL.md files
Session->>UI: session.skills_loaded
Session->>Remote: fetch custom agents if auth/provider available
Session->>Session: merge provided + discovered agents
Session->>UI: session.custom_agents_updated

Relationship to other docs

  • prompt-sources.md explains how instruction files and invoked skills become model-visible context.
  • plugin-extension-architecture.md explains plugin install/cache/config and plugin-contributed capabilities.
  • agent-task-orchestration.md explains how custom agents participate in subagent execution.
  • built-in-tool-execution-pipeline.md explains how allowed tools and tool filters affect execution.
  • settings-config-persistence.md explains skillDirectories, disabledSkills, and custom-agent settings persistence.

Created and maintained by Yingting Huang.