Skip to content

Weather Tool Example

A complete example of a tool that fetches weather data from an API.

Overview

Full Code

js
/**
 * Weather Tool - Get current weather for any city
 * 
 * Demonstrates:
 * - Using context.fetch() for API calls
 * - Accessing developer secrets
 * - Input validation
 * - Error handling
 * - Structured return values
 */

async function handler(input, context) {
  const { city, units = 'metric' } = input;
  
  // Validate input
  if (!city) {
    return { 
      error: true, 
      message: 'City is required. Please specify a city name.' 
    };
  }
  
  // Get API key from secrets
  const apiKey = context.secrets.WEATHER_API_KEY;
  
  if (!apiKey) {
    return { 
      error: true, 
      message: 'Weather API key not configured. Please add your WeatherAPI.com key.' 
    };
  }
  
  try {
    // Make API request
    const response = await context.fetch(
      `https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${encodeURIComponent(city)}&aqi=yes`
    );
    
    // Handle HTTP errors
    if (!response.ok) {
      if (response.status === 400) {
        return { error: true, message: `City "${city}" not found.` };
      }
      if (response.status === 401) {
        return { error: true, message: 'Invalid API key.' };
      }
      return { error: true, message: `Weather API error: ${response.status}` };
    }
    
    // Parse response
    const data = JSON.parse(response.body);
    
    // Format response based on units preference
    const useMetric = units === 'metric';
    
    return {
      location: {
        city: data.location.name,
        region: data.location.region,
        country: data.location.country,
        localTime: data.location.localtime,
      },
      current: {
        temperature: useMetric ? data.current.temp_c : data.current.temp_f,
        temperatureUnit: useMetric ? '°C' : '°F',
        feelsLike: useMetric ? data.current.feelslike_c : data.current.feelslike_f,
        condition: data.current.condition.text,
        humidity: data.current.humidity,
        windSpeed: useMetric ? data.current.wind_kph : data.current.wind_mph,
        windSpeedUnit: useMetric ? 'km/h' : 'mph',
        windDirection: data.current.wind_dir,
        uvIndex: data.current.uv,
        visibility: useMetric ? data.current.vis_km : data.current.vis_miles,
        visibilityUnit: useMetric ? 'km' : 'miles',
      },
      airQuality: data.current.air_quality ? {
        usEpaIndex: data.current.air_quality['us-epa-index'],
        pm25: data.current.air_quality.pm2_5,
        pm10: data.current.air_quality.pm10,
      } : null,
    };
    
  } catch (error) {
    return { 
      error: true, 
      message: error.message || 'Failed to fetch weather data' 
    };
  }
}

module.exports = { handler };

Manifest

json
{
  "trigger": "auto",
  "developerSecrets": {
    "WEATHER_API_KEY": {
      "description": "API key from weatherapi.com (free tier available)",
      "required": true
    }
  },
  "tool": {
    "name": "get_weather",
    "description": "Get current weather conditions for any city. Returns temperature, humidity, wind, and air quality. Use when users ask about weather, temperature, or outdoor conditions.",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "City name (e.g., 'London', 'New York', 'Tokyo'). Can include country for clarity: 'Paris, France'"
        },
        "units": {
          "type": "string",
          "enum": ["metric", "imperial"],
          "description": "Temperature and speed units. 'metric' for Celsius/km, 'imperial' for Fahrenheit/miles. Default: metric"
        }
      },
      "required": ["city"]
    }
  }
}

Setup

  1. Get API Key

    • Sign up at WeatherAPI.com
    • Free tier: 1 million calls/month
    • Copy your API key
  2. Create Agent

    • Go to Agents in PIE
    • Click "Create Agent"
    • Select "Tool" tier
    • Paste the code and manifest
  3. Add Secret

    • After creating, go to agent settings
    • Add your WEATHER_API_KEY
  4. Test

    • Enable the agent
    • Ask PIE: "What's the weather in Tokyo?"

Example Interaction

User: What's the weather like in London?

PIE calls: get_weather({ city: "London" })

Agent returns:

json
{
  "location": {
    "city": "London",
    "region": "City of London, Greater London",
    "country": "United Kingdom",
    "localTime": "2024-01-15 14:30"
  },
  "current": {
    "temperature": 8,
    "temperatureUnit": "°C",
    "feelsLike": 5,
    "condition": "Partly cloudy",
    "humidity": 76,
    "windSpeed": 19,
    "windSpeedUnit": "km/h",
    "windDirection": "WSW",
    "uvIndex": 1,
    "visibility": 10,
    "visibilityUnit": "km"
  }
}

PIE responds: "In London, it's currently 8°C (feels like 5°C) with partly cloudy skies. The humidity is 76% with winds from the WSW at 19 km/h."

Key Patterns

Input Validation

js
if (!city) {
  return { error: true, message: 'City is required' };
}

Secret Validation

js
const apiKey = context.secrets.WEATHER_API_KEY;
if (!apiKey) {
  return { error: true, message: 'API key not configured' };
}

URL Encoding

js
encodeURIComponent(city)  // "New York" → "New%20York"

Error Handling

js
if (!response.ok) {
  if (response.status === 400) {
    return { error: true, message: `City "${city}" not found.` };
  }
  // ...
}

Structured Return

Return clean, structured data that the AI can easily understand and summarize.

Built with VitePress