Files
SergeyMenshykh 08541ee5a9 .NET: [Breaking] Refactor AgentSkill API to async resource and script lookup (#6030)
* .NET: Refactor AgentSkill API to async resource and script lookup

Replace property-based AgentSkill.Content, Resources, and Scripts with
async-by-name lookup methods plus boolean availability flags:

- Content (string getter) -> GetContentAsync(CancellationToken)
- Resources (full list) -> HasResources + GetResourceAsync(name, ct)
- Scripts (full list) -> HasScripts + GetScriptAsync(name, ct)

This makes the API friendlier for sources like MCP where enumerating all
resources up front is expensive or impossible, and allows skill implementations
to fetch content lazily.

Subclass changes:
- AgentFileSkill and AgentInlineSkill implement the new async API while
  preserving content caching.
- AgentClassSkill<TSelf> keeps virtual Resources/Scripts properties for
  reflection-based discovery and seals the new HasResources/HasScripts/
  GetResourceAsync/GetScriptAsync overrides. Its previously non-thread-safe
  lazy initialization is replaced with Lazy<T> (default thread-safety) wired
  up in a new protected constructor, so concurrent first-access from multiple
  threads is safe.
- AgentSkillsProvider calls the new async API and exposes 
ead_skill_resource
  / load_skill / 
un_skill_script tools that await the per-name lookups.

Includes baseline CompatibilitySuppressions.xml entries for the removed
property getters.

Tests:
- Direct coverage for HasResources, HasScripts, GetResourceAsync, and
  GetScriptAsync on all three skill implementations (positive, missing-name,
  and no-resources/no-scripts cases).
- Thread-safety regression test for AgentClassSkill<TSelf> that exercises
  concurrent first-access to Resources, Scripts, and GetContentAsync from
  many tasks and asserts all observers see the same cached instance.
- Provider-level coverage for the 
ead_skill_resource tool (invocation +
  error paths) and for the previously untested error paths of load_skill
  and 
un_skill_script (empty names, skill/resource/script not found).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review comments

- Move GetScriptAsync inside try/catch in RunSkillScriptAsync for error-handling parity
- Remove dead _reflectedResources branch from AgentSkillTestExtensions
- Fix XML docs to reference virtual Resources/Scripts properties (not sealed methods)
- Add Async suffix to async test methods per naming convention
- Make no-await tests synchronous to eliminate CS1998

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix formatting: add UTF-8 BOM and remove unused using

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix XML cref: Resources/Scripts are on AgentClassSkill<TSelf>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove HasResources and HasScripts properties from AgentSkill

Drop the virtual HasResources and HasScripts properties from AgentSkill
and all concrete subclasses (AgentFileSkill, AgentInlineSkill,
AgentClassSkill). AgentSkillsProvider now always includes all three
tools (load_skill, read_skill_resource, run_skill_script) and both
instruction blocks, since the tools already handle missing
resources/scripts gracefully.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add blank line for readability in file-based skills sample

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix HostedAgentSkillsPatternTests for always-included tools

Update assertions to expect read_skill_resource and run_skill_script
tools are always present, matching the new behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
08541ee5a9 · 2026-05-25 17:16:03 +00:00
History
..
2026-04-03 11:27:36 +00:00

AgentSkills Samples

Samples demonstrating Agent Skills capabilities. Each sample shows a different way to define and use skills.

Sample Description
Agent_Step01_FileBasedSkills Define skills as SKILL.md files on disk with reference documents. Uses a unit-converter skill.
Agent_Step02_CodeDefinedSkills Define skills entirely in C# code using AgentInlineSkill, with static/dynamic resources and scripts.
Agent_Step03_ClassBasedSkills Define skills as C# classes using AgentClassSkill.
Agent_Step04_MixedSkills (Advanced) Combine file-based, code-defined, and class-based skills using AgentSkillsProviderBuilder.
Agent_Step05_SkillsWithDI Use Dependency Injection with both code-defined (AgentInlineSkill) and class-based (AgentClassSkill) skills.

Key Concepts

Skill Types

Aspect File-Based Code-Defined Class-Based
Definition SKILL.md files on disk AgentInlineSkill instances in C# Classes extending AgentClassSkill
Resources All files in skill directory (filtered by extension) AddResource (static value or delegate-backed) CreateResource factory methods
Scripts Supported via script runner delegate AddScript delegates CreateScript factory methods
Discovery Automatic from directory path Explicit via constructor Explicit via constructor
Dynamic content No (static files only) Yes (factory delegates) Yes (factory delegates)
Sharing pattern Copy skill directory Inline or shared instances Package in shared assemblies/NuGet
DI support No Yes (via IServiceProvider parameter) Yes (via IServiceProvider parameter)

AgentSkillsProvider vs AgentSkillsProviderBuilder

For single-source scenarios, use the AgentSkillsProvider constructors directly — they accept a skill directory path, a set of skills, or a custom source.

Use AgentSkillsProviderBuilder for advanced scenarios where simple constructors are insufficient:

  • Mixed skill types — combine file-based, code-defined, and class-based skills in one provider
  • Multiple file script runners — use different script runners for different file skill directories
  • Skill filtering — include or exclude skills using a predicate

See Agent_Step04_MixedSkills for a working example.