2024-05-17 01:22:07 +00:00
|
|
|
import defaultKy, { type KyInstance } from 'ky'
|
|
|
|
import { z } from 'zod'
|
|
|
|
|
2024-06-02 23:31:09 +00:00
|
|
|
import { aiFunction, AIFunctionsProvider } from '../fns.js'
|
2024-05-17 01:38:36 +00:00
|
|
|
import { assert, getEnv } from '../utils.js'
|
2024-05-17 01:22:07 +00:00
|
|
|
|
|
|
|
export namespace weatherapi {
|
|
|
|
export const BASE_URL = 'https://api.weatherapi.com/v1'
|
|
|
|
|
|
|
|
export interface CurrentWeatherResponse {
|
|
|
|
current: CurrentWeather
|
|
|
|
location: WeatherLocation
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface CurrentWeather {
|
|
|
|
cloud: number
|
|
|
|
condition: WeatherCondition
|
|
|
|
feelslike_c: number
|
|
|
|
feelslike_f: number
|
|
|
|
gust_kph: number
|
|
|
|
gust_mph: number
|
|
|
|
humidity: number
|
|
|
|
is_day: number
|
|
|
|
last_updated: string
|
|
|
|
last_updated_epoch: number
|
|
|
|
precip_in: number
|
|
|
|
precip_mm: number
|
|
|
|
pressure_in: number
|
|
|
|
pressure_mb: number
|
|
|
|
temp_c: number
|
|
|
|
temp_f: number
|
|
|
|
uv: number
|
|
|
|
vis_km: number
|
|
|
|
vis_miles: number
|
|
|
|
wind_degree: number
|
|
|
|
wind_dir: string
|
|
|
|
wind_kph: number
|
|
|
|
wind_mph: number
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface WeatherCondition {
|
|
|
|
code: number
|
|
|
|
icon: string
|
|
|
|
text: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface WeatherLocation {
|
|
|
|
country: string
|
|
|
|
lat: number
|
|
|
|
localtime: string
|
|
|
|
localtime_epoch: number
|
|
|
|
lon: number
|
|
|
|
name: string
|
|
|
|
region: string
|
|
|
|
tz_id: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface WeatherIPInfoResponse {
|
|
|
|
ip: string
|
|
|
|
type: string
|
|
|
|
continent_code: string
|
|
|
|
continent_name: string
|
|
|
|
country_code: string
|
|
|
|
country_name: string
|
|
|
|
is_eu: string
|
|
|
|
geoname_id: number
|
|
|
|
city: string
|
|
|
|
region: string
|
|
|
|
lat: number
|
|
|
|
lon: number
|
|
|
|
tz_id: string
|
|
|
|
localtime_epoch: number
|
|
|
|
localtime: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-02 23:31:09 +00:00
|
|
|
export class WeatherClient extends AIFunctionsProvider {
|
2024-05-21 13:52:06 +00:00
|
|
|
readonly ky: KyInstance
|
|
|
|
readonly apiKey: string
|
|
|
|
readonly apiBaseUrl: string
|
2024-05-17 01:22:07 +00:00
|
|
|
|
|
|
|
constructor({
|
|
|
|
apiKey = getEnv('WEATHER_API_KEY'),
|
|
|
|
apiBaseUrl = weatherapi.BASE_URL,
|
|
|
|
ky = defaultKy
|
|
|
|
}: {
|
|
|
|
apiKey?: string
|
|
|
|
apiBaseUrl?: string
|
|
|
|
ky?: KyInstance
|
|
|
|
} = {}) {
|
2024-05-26 06:43:10 +00:00
|
|
|
assert(
|
|
|
|
apiKey,
|
|
|
|
'WeatherClient missing required "apiKey" (defaults to "WEATHER_API_KEY")'
|
|
|
|
)
|
2024-05-17 01:22:07 +00:00
|
|
|
super()
|
|
|
|
|
|
|
|
this.apiKey = apiKey
|
|
|
|
this.apiBaseUrl = apiBaseUrl
|
|
|
|
|
2024-05-21 13:52:06 +00:00
|
|
|
this.ky = ky.extend({ prefixUrl: apiBaseUrl })
|
2024-05-17 01:22:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@aiFunction({
|
2024-05-23 23:19:38 +00:00
|
|
|
name: 'get_current_weather',
|
2024-05-17 01:22:07 +00:00
|
|
|
description: 'Gets info about the current weather at a given location.',
|
2024-05-21 13:52:06 +00:00
|
|
|
inputSchema: z.object({
|
2024-05-17 01:22:07 +00:00
|
|
|
q: z
|
|
|
|
.string()
|
|
|
|
.describe(
|
|
|
|
'Location to get the weather for. May be a city name, zipcode, IP address, or lat/lng coordinates. Example: "London"'
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
async getCurrentWeather(queryOrOptions: string | { q: string }) {
|
|
|
|
const options =
|
|
|
|
typeof queryOrOptions === 'string'
|
|
|
|
? { q: queryOrOptions }
|
|
|
|
: queryOrOptions
|
|
|
|
|
2024-05-21 13:52:06 +00:00
|
|
|
return this.ky
|
2024-05-17 01:22:07 +00:00
|
|
|
.get('current.json', {
|
|
|
|
searchParams: {
|
|
|
|
key: this.apiKey,
|
|
|
|
...options
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.json<weatherapi.CurrentWeatherResponse>()
|
|
|
|
}
|
|
|
|
}
|