@@ -34,7 +34,7 @@ export const mastra = new Mastra({
3434
3535 Your primary function is to help users get weather details for specific locations. When responding:
3636 - Always ask for a location if none is provided
37- - If the location name isn’ t in English, please translate it
37+ - If the location name isn' t in English, please translate it
3838 - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
3939 - Include relevant details like humidity, wind conditions, and precipitation
4040 - Keep responses concise but informative
@@ -53,6 +53,84 @@ export const mastra = new Mastra({
5353 } ,
5454 } ,
5555 } ) ,
56+ tools : {
57+ weatherTool : createTool ( {
58+ id : "weatherTool" ,
59+ description : "Get current weather for a location" ,
60+ inputSchema : z . object ( {
61+ location : z . string ( ) . describe ( "The location to get weather for" ) ,
62+ } ) ,
63+ outputSchema : z . string ( ) ,
64+ execute : async ( { context } ) => {
65+ const { location } = context ;
66+
67+ try {
68+ // Use OpenWeatherMap API or similar weather service
69+ // For now, we'll use a free weather API (Open-Meteo)
70+ const geocodeResponse = await fetch (
71+ `https://geocoding-api.open-meteo.com/v1/search?name=${ encodeURIComponent ( location ) } &count=1&language=en&format=json`
72+ ) ;
73+
74+ if ( ! geocodeResponse . ok ) {
75+ throw new Error ( `Geocoding failed: ${ geocodeResponse . status } ` ) ;
76+ }
77+
78+ const geocodeData = await geocodeResponse . json ( ) ;
79+
80+ if ( ! geocodeData . results || geocodeData . results . length === 0 ) {
81+ return `Sorry, I couldn't find weather data for "${ location } ". Please check the location name and try again.` ;
82+ }
83+
84+ const { latitude, longitude, name, country } = geocodeData . results [ 0 ] ;
85+
86+ // Get weather data
87+ const weatherResponse = await fetch (
88+ `https://api.open-meteo.com/v1/forecast?latitude=${ latitude } &longitude=${ longitude } ¤t=temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code&timezone=auto`
89+ ) ;
90+
91+ if ( ! weatherResponse . ok ) {
92+ throw new Error ( `Weather API failed: ${ weatherResponse . status } ` ) ;
93+ }
94+
95+ const weatherData = await weatherResponse . json ( ) ;
96+
97+ if ( ! weatherData . current ) {
98+ return `Sorry, I couldn't retrieve current weather data for "${ location } ". The weather service might be temporarily unavailable.` ;
99+ }
100+
101+ const current = weatherData . current ;
102+ const temperature = current . temperature_2m ;
103+ const humidity = current . relative_humidity_2m ;
104+ const windSpeed = current . wind_speed_10m ;
105+ const weatherCode = current . weather_code ;
106+
107+ // Simple weather code mapping
108+ const getWeatherCondition = ( code : number ) : string => {
109+ if ( code === 0 ) return "Clear sky" ;
110+ if ( code <= 3 ) return "Partly cloudy" ;
111+ if ( code <= 48 ) return "Foggy" ;
112+ if ( code <= 67 ) return "Rainy" ;
113+ if ( code <= 77 ) return "Snowy" ;
114+ if ( code <= 82 ) return "Rainy" ;
115+ if ( code <= 86 ) return "Snowy" ;
116+ return "Stormy" ;
117+ } ;
118+
119+ const condition = getWeatherCondition ( weatherCode ) ;
120+
121+ return `The current weather in ${ name } , ${ country } is as follows:
122+ Temperature: ${ temperature } °C
123+ Humidity: ${ humidity } %
124+ Wind Speed: ${ windSpeed } km/h
125+ Conditions: ${ condition } ` ;
126+
127+ } catch ( error ) {
128+ console . error ( "Weather tool error:" , error ) ;
129+ return `I'm sorry, but I'm having trouble retrieving weather data for "${ location } " at the moment. This could be due to a temporary service issue. Please try again later or check another weather source.` ;
130+ }
131+ } ,
132+ } ) ,
133+ } ,
56134 } ) ,
57135 shared_state : new Agent ( {
58136 name : "shared_state" ,
0 commit comments