Skip to main content

🛠️ Skills Module

The skills/ module provides the tools and capabilities system for agents.


Module Overview


File Structure

src/openstackai/skills/
├── __init__.py
├── skill.py # Base Skill class
├── tool_skill.py # Tool decorator
├── action_skill.py # Action-based skills
├── builtin.py # Built-in skills
└── registry.py # Skill registry

@tool Decorator

The simplest way to create agent tools.

Basic Usage

from openstackai.skills import tool

@tool(description="Get the current weather for a city")
async def get_weather(city: str) -> str:
"""Get weather information."""
# Implementation
return f"Weather in {city}: Sunny, 72°F"

@tool(description="Calculate the sum of two numbers")
async def add(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b

With Schema

from openstackai.skills import tool
from pydantic import BaseModel, Field

class SearchParams(BaseModel):
query: str = Field(description="Search query")
max_results: int = Field(default=10, description="Maximum results")

@tool(
description="Search the web",
schema=SearchParams
)
async def web_search(query: str, max_results: int = 10) -> list:
"""Search the web for information."""
# Implementation
return [{"title": "Result 1", "url": "..."}]

Tool Registration

from openstackai import Agent

# Create agent with tools
agent = Agent(
name="Assistant",
instructions="You are helpful.",
tools=[get_weather, add, web_search]
)

Tool Execution Flow


Skill Class

For more complex, stateful tools.

from openstackai.skills import Skill

class DatabaseSkill(Skill):
"""Skill for database operations."""

name = "database"
description = "Query and modify database"

def __init__(self, connection_string: str):
super().__init__()
self.connection = self._connect(connection_string)

async def execute(self, action: str, **params) -> Any:
if action == "query":
return await self._query(params["sql"])
elif action == "insert":
return await self._insert(params["table"], params["data"])

def get_tools(self) -> list:
"""Return tools exposed by this skill."""
return [
self._create_tool("query", "Execute SQL query"),
self._create_tool("insert", "Insert data")
]

SkillRegistry

Manage and discover skills.

from openstackai.skills import SkillRegistry

registry = SkillRegistry()

# Register skills
registry.register(DatabaseSkill("..."))
registry.register(WebSearchSkill())

# Get skill
db_skill = registry.get("database")

# List all skills
all_skills = registry.list_skills()

# Get all tools
all_tools = registry.get_all_tools()

Built-in Skills

SearchSkill

from openstackai.skills.builtin import SearchSkill

search = SearchSkill(
api_key="...",
engine="google" # or "bing", "duckduckgo"
)

results = await search.search("Python tutorials")

CodeSkill

from openstackai.skills.builtin import CodeSkill

code = CodeSkill()

# Execute code safely
result = await code.execute("""
def fibonacci(n):
if n <= 1: return n
return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))
""")

FileSkill

from openstackai.skills.builtin import FileSkill

file = FileSkill(base_path="./workspace")

# Read file
content = await file.read("document.txt")

# Write file
await file.write("output.txt", content)

# List directory
files = await file.list("./")

WebSkill

from openstackai.skills.builtin import WebSkill

web = WebSkill()

# Fetch URL
html = await web.fetch("https://example.com")

# Extract text
text = await web.extract_text("https://example.com")

MathSkill

from openstackai.skills.builtin import MathSkill

math = MathSkill()

# Calculate
result = await math.calculate("2 + 2 * 3")

# Symbolic math
solution = await math.solve("x^2 + 2x + 1 = 0")

Creating Custom Skills

Simple Tool

from openstackai.skills import tool

@tool(description="Get stock price")
async def get_stock_price(symbol: str) -> dict:
"""Fetch current stock price."""
# API call
return {"symbol": symbol, "price": 150.0, "change": "+2.5%"}

Complex Skill Class

from openstackai.skills import Skill, tool
from typing import List, Dict, Any

class CRMSkill(Skill):
"""Customer relationship management skill."""

name = "crm"
description = "Manage customer data and interactions"

def __init__(self, api_url: str, api_key: str):
super().__init__()
self.api_url = api_url
self.api_key = api_key

@tool(description="Search for customers")
async def search_customers(
self,
query: str,
limit: int = 10
) -> List[Dict]:
"""Search customer database."""
# Implementation
return [{"id": 1, "name": "John Doe"}]

@tool(description="Get customer details")
async def get_customer(self, customer_id: int) -> Dict:
"""Get customer by ID."""
return {"id": customer_id, "name": "John", "email": "..."}

@tool(description="Create new customer")
async def create_customer(
self,
name: str,
email: str,
phone: str = None
) -> Dict:
"""Create a new customer record."""
return {"id": 123, "name": name, "created": True}

Skill Architecture


Best Practices

1. Clear Descriptions

# Good
@tool(description="Get the current temperature in Fahrenheit for a city")
async def get_temperature(city: str) -> float: ...

# Bad
@tool(description="temp")
async def get_temp(c: str): ...

2. Type Hints

# Good - LLM understands parameters
@tool(description="Calculate compound interest")
async def compound_interest(
principal: float,
rate: float,
years: int,
compounds_per_year: int = 12
) -> float: ...

3. Error Handling

@tool(description="Fetch URL content")
async def fetch_url(url: str) -> str:
try:
response = await client.get(url)
return response.text
except Exception as e:
return f"Error fetching URL: {e}"

➡️ [[Kernel-Module]] | [[Blueprint-Module]] | [[Home]]