Files
SergeyMenshykh 1d94518f37 Python: Add ClassSkill for class-based skill definitions (#5678)
* Python: Add ClassSkill for class-based skill definitions

Add ClassSkill abstract base class with decorator-based resource and script
discovery, porting .NET's AgentClassSkill (PRs #5027 and #5183) to Python.

- Add ClassSkill(Skill, ABC) with instructions abstract property, cached
  content/resources/scripts properties
- Add @ClassSkill.resource and @ClassSkill.script static method decorators
  for auto-discovery of methods and properties
- Extract _build_skill_content() and _create_resource_element() shared
  helpers from InlineSkill for reuse
- Add _discover_marked_members() for scanning class hierarchies
- Add _make_method_name() for Python-to-skill name conversion
- Add class_based_skill sample (UnitConverterSkill)
- Update mixed_skills sample with TemperatureConverterSkill
- Add 58 new tests covering ClassSkill, decorator discovery, property
  resources, inheritance, kwargs forwarding, and duplicate detection
- Export ClassSkill from agent_framework public API

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

* fix: replace try/except/continue with assignment to satisfy bandit B112

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

* address PR review feedback

- Walk cls.__mro__ in _discover_marked_members for inherited property resources
- Use inspect.getattr_static for MRO-aware is_property check
- Return defensive copies from resources/scripts properties
- Raise TypeError on wrong decorator stacking order (@resource above @property)
- Log warning instead of silently swallowing descriptor errors during discovery
- Validate explicit name= at decoration time via _validate_member_name
- Add tests for all of the above

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

* Fix temperature converter skill: make resource necessary for script

Refactor TemperatureConverterSkill so the agent must read the
formulas resource (factor/offset) before calling the script,
aligning with the volume-converter pattern.

- Resource: numeric factor/offset table instead of symbolic formulas
- Script: generic linear transform (value * factor + offset)
- Instructions: updated to reflect new workflow

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 19:39:12 +00:00

2.0 KiB
Raw Permalink Blame History

Class-Based Agent Skills

This sample demonstrates how to define Agent Skills as Python classes using ClassSkill.

What's Demonstrated

  • Creating skills as classes that extend ClassSkill
  • Bundling name, description, instructions, resources, and scripts into a single class
  • Using @ClassSkill.resource decorator for automatic resource discovery
  • Using @ClassSkill.script decorator for automatic script discovery
  • Lazy-loading and caching of resources and scripts
  • Registering class-based skills with SkillsProvider

Skills Included

unit-converter (class-based)

A UnitConverterSkill class that converts between common units. Defined in class_based_skill.py:

  • conversion-table — Static resource with factor table
  • convert — Script that performs value × factor conversion

Project Structure

class_based_skill/
├── class_based_skill.py
└── README.md

Running the Sample

Prerequisites

Environment Variables

Set the required environment variables in a .env file (see python/.env.example):

  • FOUNDRY_PROJECT_ENDPOINT: Your Azure AI Foundry project endpoint
  • FOUNDRY_MODEL: The name of your model deployment (defaults to gpt-4o-mini)

Authentication

This sample uses AzureCliCredential for authentication. Run az login in your terminal before running the sample.

Run

cd python
uv run samples/02-agents/skills/class_based_skill/class_based_skill.py

Expected Output

Converting units with class-based skills
------------------------------------------------------------
Agent: Here are your conversions:

1. **26.2 miles → 42.16 km** (a marathon distance)
2. **75 kg → 165.35 lbs**

Learn More