Skip to content

feat: add agent skills support for declarative agents#15607

Open
sebastienlevert wants to merge 20 commits intoOfficeDev:devfrom
sebastienlevert:feature/agent-skills-support
Open

feat: add agent skills support for declarative agents#15607
sebastienlevert wants to merge 20 commits intoOfficeDev:devfrom
sebastienlevert:feature/agent-skills-support

Conversation

@sebastienlevert
Copy link
Copy Markdown
Contributor

@sebastienlevert sebastienlevert commented Mar 27, 2026

Feature: https://msazure.visualstudio.com/Microsoft%20Teams%20Extensibility/_workitems/edit/37278479

Summary

This PR adds comprehensive Agent Skills support to the Microsoft 365 Agents Toolkit, enabling declarative agents to bundle reusable skill definitions. Skills are markdown-based instruction sets (SKILL.md files) that can be packaged within the appPackage and referenced from the declarative agent manifest.

What are Agent Skills?

Agent Skills allow declarative agent authors to decompose agent behavior into modular, reusable instruction bundles. Each skill:

  • Lives in a folder under appPackage/skills/{skill-name}/
  • Contains a SKILL.md file with frontmatter (name, description) and markdown instructions
  • Is referenced in the declarative agent manifest via the agent_skills property
  • Can optionally be exposed to mainline M365 Copilot via expose_skill_to_copilot

Changes by Package

@microsoft/app-manifest (packages/manifest)

  • v1.7 Declarative Agent JSON schema with agent_skills as a first-class property
  • AgentSkillElement type: folder (required string) + expose_skill_to_copilot (optional boolean)
  • Auto-generated TypeScript types from the new schema
  • Updated DeclarativeAgentManifestWrapper with full skill CRUD operations:
    • addSkill(), removeSkill(), getSkill(), hasSkill(), getSkills()
  • Schema validation support for the new manifest version
  • 51+ unit tests covering all manifest operations

@microsoft/teamsfx-core (packages/fx-core)

  • FxCore.addSkill() lifecycle method following the established addPlugin/addKnowledge patterns
  • Question flow (addSkillQuestionNode) with:
    • Skill name input with inline validation (letters, numbers, hyphens; duplicate detection)
    • Skill description input
    • Expose to M365 Copilot (Yes/No quickpick, defaults to No)
    • Manifest file selector
  • copilotGptManifestUtils.addSkill() to update the DA manifest with new skill entries
  • Scaffolding: creates skills/{name}/SKILL.md with frontmatter and template content
  • --from flag for importing existing skill folders:
    • Validates folder name format (letters, numbers, hyphens only)
    • Validates SKILL.md exists in the folder
    • Validates name: frontmatter matches the folder name
    • Skips name/description prompts when --from is provided
  • Validation: max 10 skills per agent, skills must be within appPackage boundary
  • Warn-level confirmation dialog before modifying files (matching addPlugin pattern)
  • Success notification with "View agent manifest" button
  • 13 unit tests covering all paths

@microsoft/m365agentstoolkit-cli (packages/cli)

  • atk add skill CLI command with options:
    • --name — Skill name (required for new skills)
    • --description — Skill description (required for new skills)
    • --expose-to-copilot — Yes/No, defaults to No
    • --from — Import existing skill folder
    • --manifest-file — App manifest path (defaults to ./appPackage/manifest.json)

VS Code Extension (packages/vscode-extension)

  • "Add Skill" tree view item in the Development section (lightbulb icon)
    • Only visible for declarative agent projects (isDeclarativeCopilotApp)
    • Positioned after "Add Action" in the tree
  • fx-extension.addSkill command with proper enablement conditions
  • Localization keys added across all 16 locale files
  • Full quickpick-based UX flow (no modal dialogs for questions)

CLI Usage Examples

# Create a new skill (interactive)
atk add skill -i

# Create a new skill (non-interactive)
atk add skill --name my-search-skill --description "Searches internal docs"

# Create with M365 Copilot exposure
atk add skill --name my-skill --description "A skill" --expose-to-copilot yes

# Import an existing skill folder
atk add skill --from skills/existing-skill

Validation Rules

Rule Error
Skill name must match ^[a-zA-Z][a-zA-Z0-9-]*$ Inline validation error
Skill folder already exists "A skill named 'X' already exists"
Max 10 skills per agent SkillLimitExceeded
Skill folder must be within appPackage SkillOutsideAppPackage
SKILL.md must exist (for --from) SkillMdNotFound
SKILL.md name must match folder name (for --from) SkillNameMismatch
Folder name format (for --from) InvalidSkillFolderName

Testing

  • Manifest package: 51+ unit tests (schema validation, wrapper CRUD, converters)
  • FxCore: 13 unit tests (scaffolding, validation, error paths, confirm dialog, --from)
  • All tests passing locally

sebastienlevert and others added 10 commits March 26, 2026 12:29
Add end-to-end support for agent skills in M365 Agents Toolkit:

- Manifest wrapper: AgentSkillElement, CRUD operations (add/remove/has/get),
  max 10 skills, x-agent_skills extension property with agent_skills fallback
- Packaging: bundle skill directories in createAppPackage, validate path
  boundary and SKILL.md existence
- Validation: skill folder/SKILL.md/frontmatter validation, error aggregation,
  telemetry, log formatting for CLI and VS Code
- FxCore.addSkill(): new/existing skill flows, SKILL.md template generation,
  path normalization, confirmation dialog
- Question flow: skill name, description, expose-to-copilot questions
- CLI: atk add skill command with options and telemetry
- VS Code: handler, command registration, telemetry events
- Localization: all English strings for prompts and messages
- Tests: 51 new unit tests across wrapper, packaging, validation, and command

Co-authored-by: Copilot <[email protected]>
…ore conflict

- Rename checkCopilotAccess.title to checkCopilotAccess in all 16 nls files
  to match the %teamstoolkit.commands.checkCopilotAccess% reference in package.json
- Remove redundant 'files' property from package.json since .vscodeignore
  is used for vsce packaging (newer vsce rejects having both)

Co-authored-by: Copilot <[email protected]>
- Add TreeViewCommand for addSkill below Add Action in the Development pane
- Add fx-extension.addSkill command entry in package.json with enablement
- Add localization keys (title, description, running, blockTooltip) across all 16 locales
- Remove diagnostic logging from localizeUtils.ts and treeViewCommand.ts
- Skill item shows only for declarative agent projects (isDeclarativeCopilotApp)

Co-authored-by: Copilot <[email protected]>
- Replace ConfirmQuestion with SingleSelectQuestion (yes/no options)
- Update FxCore.addSkill to compare string 'yes' instead of boolean
- Add localization keys for yes/no options
- Update CLI option type from boolean to string
- Update tests accordingly - all 11 passing

Co-authored-by: Copilot <[email protected]>
The addSkill flow had a showMessage() confirm dialog before proceeding,
which interrupted the quickpick-only UX. Remove it so the flow stays
entirely within the VS Code quickpick area.

Co-authored-by: Copilot <[email protected]>
Adds back the warn-level showMessage confirmation (matching addPlugin
pattern) that asks users to confirm before modifying files. This was
accidentally removed when the pre-action confirmation was stripped.

Co-authored-by: Copilot <[email protected]>
- Allow uppercase letters in skill names (not just lowercase)
- Validate for duplicate skill names (check if folder already exists)
- Rename CLI flags: --name, --description, --expose-to-copilot, --from
- Update validation error messages and placeholder text

Co-authored-by: Copilot <[email protected]>
When adding an existing skill via --from, the name and description are
already in the SKILL.md file, so they shouldn't be required. Skip the
name/description prompts in the question flow when --from is provided.

Co-authored-by: Copilot <[email protected]>
When importing an existing skill via --from:
- Validate folder name uses only letters, numbers, and hyphens
- Read SKILL.md frontmatter and verify the name matches the folder name
- Error out with clear messages if either check fails

Co-authored-by: Copilot <[email protected]>
@sebastienlevert sebastienlevert changed the base branch from main to dev March 27, 2026 01:11
Add AgentSkillsEnabled feature flag (default: false) following the
established pattern (like EmbeddedKnowledge before cleanup). Gates:
- VS Code tree view item (treeViewManager.ts)
- VS Code command enablement (package.json)
- VS Code context (extension.ts setContext)
- CLI 'atk add skill' command (add.ts)

Set TEAMSFX_AGENT_SKILLS=true to enable the feature.

Co-authored-by: Copilot <[email protected]>
return { props, additional };
}

function m(additional: any) {

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note generated

Unused function m.
sebastienlevert and others added 3 commits March 27, 2026 02:30
Add re-export of AgentSkillElement interface so it can be imported by
consumers and test files. Previously the type was imported from
generated-types and used internally but not re-exported, causing
TS2459 errors in the manifest test suite.

Co-authored-by: Copilot <[email protected]>
Copy link
Copy Markdown
Contributor

@tecton tecton left a comment

Choose a reason for hiding this comment

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

I met "(×) Error: unknown.InternalError: The "path" argument must be of type string. Received undefined" when running atk new skill under DA project. Could you please fix it?

@sebastienlevert
Copy link
Copy Markdown
Contributor Author

I met "(×) Error: unknown.InternalError: The "path" argument must be of type string. Received undefined" when running atk new skill under DA project. Could you please fix it?

Do you mean atk add skill?

@tecton
Copy link
Copy Markdown
Contributor

tecton commented Mar 27, 2026

I met "(×) Error: unknown.InternalError: The "path" argument must be of type string. Received undefined" when running atk new skill under DA project. Could you please fix it?

Do you mean atk add skill?

Yes, sorry it's a typo.
image

@sebastienlevert
Copy link
Copy Markdown
Contributor Author

Please make sure you have the environment variable available.

$env:TEAMSFX_AGENT_SKILLS = "true"

I can run it locally here

image

sebastienlevert and others added 2 commits March 27, 2026 03:48
- Use path.resolve(projectPath, teamsManifestPath) for manifest file
  resolution to handle both absolute and relative paths correctly
- Revert localized package.nls.*.json files (pipeline handles translations)

Co-authored-by: Copilot <[email protected]>
- Update treeViewManager test to expect 9 items (Add Skill added)
- Apply prettier formatting to CopilotGptManifestUtils and test files

Co-authored-by: Copilot <[email protected]>
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 93.62550% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.76%. Comparing base (8b200eb) to head (a569e13).

Files with missing lines Patch % Lines
packages/cli/src/commands/models/addSkill.ts 54.54% 5 Missing ⚠️
...vscode-extension/src/handlers/lifecycleHandlers.ts 33.33% 4 Missing ⚠️
...ckages/vscode-extension/src/handlers/sharedOpts.ts 0.00% 2 Missing ⚠️
packages/cli/src/commands/models/add.ts 75.00% 0 Missing and 1 partial ⚠️
...t/driver/teamsApp/utils/CopilotGptManifestUtils.ts 98.57% 0 Missing and 1 partial ⚠️
.../fx-core/src/component/driver/teamsApp/validate.ts 88.88% 0 Missing and 1 partial ⚠️
packages/fx-core/src/core/FxCore.ts 98.46% 1 Missing ⚠️
...ges/vscode-extension/src/telemetry/extTelemetry.ts 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##              dev   #15607    +/-   ##
========================================
  Coverage   92.75%   92.76%            
========================================
  Files         622      624     +2     
  Lines       38067    38316   +249     
  Branches     7011     6942    -69     
========================================
+ Hits        35309    35543   +234     
- Misses       2026     2038    +12     
- Partials      732      735     +3     
Files with missing lines Coverage Δ
packages/cli/src/telemetry/cliTelemetryEvents.ts 100.00% <100.00%> (ø)
packages/fx-core/src/common/featureFlags.ts 100.00% <100.00%> (ø)
.../src/component/driver/teamsApp/createAppPackage.ts 97.80% <100.00%> (+0.09%) ⬆️
...e/src/component/driver/teamsApp/utils/telemetry.ts 100.00% <100.00%> (ø)
packages/fx-core/src/question/index.ts 97.22% <100.00%> (+0.07%) ⬆️
packages/fx-core/src/question/inputs/index.ts 100.00% <100.00%> (ø)
...es/fx-core/src/question/options/AddSkillOptions.ts 100.00% <100.00%> (ø)
packages/fx-core/src/question/options/index.ts 100.00% <100.00%> (ø)
packages/fx-core/src/question/other.ts 94.74% <100.00%> (+0.23%) ⬆️
packages/fx-core/src/question/questionNames.ts 100.00% <100.00%> (ø)
... and 13 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

sebastienlevert and others added 4 commits March 27, 2026 10:02
- Merge upstream/dev to stay current
- Fix CopilotGptManifestUtils.ts formatting (CI lint-pr.sh)
- Add 5 new unit tests for addSkill coverage gaps:
  - copilotExtensions manifest format path
  - Skill outside appPackage validation
  - SKILL.md without name frontmatter
  - showMessage error handling
  - DA manifest with empty file property

Co-authored-by: Copilot <[email protected]>
- Add 7 tests for addSkillQuestionNode (pattern validation, duplicates, conditions)
- Add 4 tests for logValidationErrors with skill errors (VSC + CLI)
- Add 1 test for validate driver with non-empty skillValidationResult
- Remove 3 unused NLS keys (expose.description, from.title, from.placeholder)

Co-authored-by: Copilot <[email protected]>
- Test VSCode View Agent Manifest button triggers openFile
- Test CLI platform success message path
- Test logValidationErrors with undefined skillValidationResult (covers ?? [] partials)

Co-authored-by: Copilot <[email protected]>
@sebastienlevert sebastienlevert marked this pull request as ready for review March 27, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants