SkillContext
Context object passed to skill functions with memory and workflow access
The SkillContext is passed to every skill function, providing access to memory, workflow tracking, and execution metadata. Unlike ReasonerContext, it does not include AI capabilities since skills are deterministic.
Basic Usage
agent.skill('get_user', async (ctx) => {
const { userId } = ctx.input;
// Access memory
const cached = await ctx.memory.get(`user_${userId}`);
if (cached) return cached;
// Fetch from database
const user = await database.findUser(userId);
// Cache result
await ctx.memory.set(`user_${userId}`, user);
return user;
});Properties
Input & Metadata
Prop
Type
Service Access
Prop
Type
Methods
ctx.discover()
Discover capabilities of other agents.
const discovery = await ctx.discover({
tags: ['database'],
includeDescriptions: true
});Difference from ReasonerContext
| Feature | ReasonerContext | SkillContext |
|---|---|---|
AI access (ctx.ai()) | Yes | No |
AI streaming (ctx.aiStream()) | Yes | No |
Cross-agent calls (ctx.call()) | Yes | No |
| Memory access | Yes | Yes |
| Workflow tracking | Yes | Yes |
| DID/Credentials | Yes | Yes |
| Discovery | Yes | Yes |
Skills are designed for deterministic operations like database queries, formatting, and integrations. Use reasoners when you need AI capabilities.
Examples
Database Operations
agent.skill('create_order', async (ctx) => {
const { customerId, items, total } = ctx.input;
const order = await database.orders.create({
customerId,
items,
total,
status: 'pending',
createdAt: new Date()
});
// Store in workflow memory for other agents
await ctx.memory.set(`order_${order.id}`, order);
// Track for audit
await ctx.did.generateCredential({
inputData: { customerId, itemCount: items.length },
outputData: { orderId: order.id }
});
return order;
}, { tags: ['database', 'orders'] });Data Formatting
agent.skill('format_report', async (ctx) => {
const { data, format } = ctx.input;
switch (format) {
case 'json':
return JSON.stringify(data, null, 2);
case 'csv':
return convertToCsv(data);
case 'html':
return renderHtmlTable(data);
default:
throw new Error(`Unknown format: ${format}`);
}
}, { tags: ['formatting'] });External API Integration
agent.skill('fetch_weather', async (ctx) => {
const { city } = ctx.input;
// Check cache first
const cached = await ctx.memory.get(`weather_${city}`);
if (cached && Date.now() - cached.fetchedAt < 300000) {
return cached.data;
}
// Fetch from API
const response = await fetch(
`https://api.weather.com/v1/current?city=${encodeURIComponent(city)}`
);
const data = await response.json();
// Cache for 5 minutes
await ctx.memory.set(`weather_${city}`, {
data,
fetchedAt: Date.now()
});
return data;
}, { tags: ['external-api', 'weather'] });Validation
agent.skill('validate_email', async (ctx) => {
const { email } = ctx.input;
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const domain = email.split('@')[1];
// Check against blocklist in memory
const blocklist = await ctx.memory.global_scope.get('email_blocklist') || [];
const isBlocked = blocklist.includes(domain);
return {
email,
isValid,
isBlocked,
domain
};
}, { tags: ['validation'] });Related
- ReasonerContext - Context with AI access
- ctx.memory - Memory operations
- Agent Class - Registering skills