chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# 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
|
||||
|
||||
- An [Azure AI Foundry](https://ai.azure.com/) project with a deployed model (e.g. `gpt-4o-mini`)
|
||||
|
||||
### 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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
- [Agent Skills Specification](https://agentskills.io/)
|
||||
- [Code-Defined Skills Sample](../code_defined_skill/)
|
||||
- [Mixed Skills Sample](../mixed_skills/)
|
||||
- [Microsoft Agent Framework Documentation](../../../../../docs/)
|
||||
@@ -0,0 +1,148 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
from textwrap import dedent
|
||||
|
||||
from agent_framework import Agent, ClassSkill, SkillFrontmatter, SkillsProvider, ToolApprovalMiddleware
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
"""
|
||||
Class-Based Agent Skills — Define skills as Python classes
|
||||
|
||||
This sample demonstrates how to define Agent Skills as reusable Python classes
|
||||
by subclassing ``ClassSkill``. Class-based skills bundle all components (name,
|
||||
description, instructions, resources, scripts) into a single class, making
|
||||
them easy to package and distribute via shared libraries or PyPI.
|
||||
|
||||
Key concepts shown:
|
||||
- Subclassing ``ClassSkill`` to create a self-contained skill
|
||||
- Using ``@property`` + ``@ClassSkill.resource`` (bare) — name defaults to method name
|
||||
- Using ``@ClassSkill.script(name=..., description=...)`` — explicit name and description
|
||||
- Lazy-loading and caching of resources and scripts
|
||||
"""
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Class-Based Skill: UnitConverterSkill
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class UnitConverterSkill(ClassSkill):
|
||||
"""A unit-converter skill defined as a Python class.
|
||||
|
||||
Converts between common units (miles↔km, pounds↔kg) using a
|
||||
conversion factor. Resources and scripts are discovered automatically
|
||||
via decorators.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
frontmatter=SkillFrontmatter(
|
||||
name="unit-converter",
|
||||
description=(
|
||||
"Convert between common units using a multiplication factor. "
|
||||
"Use when asked to convert miles, kilometers, pounds, or kilograms."
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@property
|
||||
def instructions(self) -> str:
|
||||
return dedent("""\
|
||||
Use this skill when the user asks to convert between units.
|
||||
|
||||
1. Review the conversion-table resource to find the factor for the requested conversion.
|
||||
2. Use the convert script, passing the value and factor from the table.
|
||||
3. Present the result clearly with both units.
|
||||
""")
|
||||
|
||||
# 1. Property with bare decorator — name defaults to the method name
|
||||
# ("conversion_table" → "conversion-table"), no description.
|
||||
# Place @property first, then @ClassSkill.resource.
|
||||
@property
|
||||
@ClassSkill.resource
|
||||
def conversion_table(self) -> str:
|
||||
"""Lookup table of multiplication factors for common unit conversions."""
|
||||
return dedent("""\
|
||||
# Conversion Tables
|
||||
|
||||
Formula: **result = value × factor**
|
||||
|
||||
| From | To | Factor |
|
||||
|-------------|-------------|----------|
|
||||
| miles | kilometers | 1.60934 |
|
||||
| kilometers | miles | 0.621371 |
|
||||
| pounds | kilograms | 0.453592 |
|
||||
| kilograms | pounds | 2.20462 |
|
||||
""")
|
||||
|
||||
# 2. Explicit name — overrides the method name
|
||||
# 3. Explicit description — provides a description for the script
|
||||
@ClassSkill.script(name="convert", description="Multiplies a value by a conversion factor.")
|
||||
def convert_units(self, value: float, factor: float) -> str:
|
||||
"""Convert a value using a multiplication factor: result = value × factor.
|
||||
|
||||
Args:
|
||||
value: The numeric value to convert.
|
||||
factor: Conversion factor from the conversion table.
|
||||
|
||||
Returns:
|
||||
JSON string with the inputs and converted result.
|
||||
"""
|
||||
result = round(value * factor, 4)
|
||||
return json.dumps({"value": value, "factor": factor, "result": result})
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Run the class-based skills demo."""
|
||||
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
|
||||
deployment = os.environ.get("FOUNDRY_MODEL", "gpt-4o-mini")
|
||||
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=endpoint,
|
||||
model=deployment,
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Instantiate the class-based skill and pass it to the provider
|
||||
unit_converter = UnitConverterSkill()
|
||||
|
||||
# All skill tools require approval by default; auto-approve them so the
|
||||
# sample runs unattended. See the script_approval / skills_auto_approval
|
||||
# samples for interactive and selective approval handling.
|
||||
async with Agent(
|
||||
client=client,
|
||||
instructions="You are a helpful assistant that can convert units.",
|
||||
context_providers=[SkillsProvider(unit_converter)],
|
||||
middleware=[ToolApprovalMiddleware(auto_approval_rules=[SkillsProvider.all_tools_auto_approval_rule])],
|
||||
) as agent:
|
||||
print("Converting units with class-based skills")
|
||||
print("-" * 60)
|
||||
session = agent.create_session()
|
||||
response = await agent.run(
|
||||
"How many kilometers is a marathon (26.2 miles)? And how many pounds is 75 kilograms?",
|
||||
session=session,
|
||||
)
|
||||
print(f"Agent: {response}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
"""
|
||||
Sample 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**
|
||||
"""
|
||||
Reference in New Issue
Block a user