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

FeatureReasonerContextSkillContext
AI access (ctx.ai())YesNo
AI streaming (ctx.aiStream())YesNo
Cross-agent calls (ctx.call())YesNo
Memory accessYesYes
Workflow trackingYesYes
DID/CredentialsYesYes
DiscoveryYesYes

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'] });