@dainprotocol/cli 1.1.1 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -6,17 +6,26 @@ import axios from "axios";
|
|
|
6
6
|
import {
|
|
7
7
|
defineDAINService,
|
|
8
8
|
ToolConfig,
|
|
9
|
-
ServiceConfig,
|
|
10
|
-
ToolboxConfig,
|
|
11
|
-
ServiceContext,
|
|
12
9
|
} from "@dainprotocol/service-sdk";
|
|
13
10
|
|
|
11
|
+
import { CardUIBuilder, TableUIBuilder, MapUIBuilder } from "@dainprotocol/utils";
|
|
12
|
+
|
|
13
|
+
const getWeatherEmoji = (temperature: number): string => {
|
|
14
|
+
if (temperature <= 0) return '🥶';
|
|
15
|
+
if (temperature <= 10) return '❄️';
|
|
16
|
+
if (temperature <= 20) return '⛅';
|
|
17
|
+
if (temperature <= 25) return '☀️';
|
|
18
|
+
if (temperature <= 30) return '🌞';
|
|
19
|
+
return '🔥';
|
|
20
|
+
};
|
|
21
|
+
|
|
14
22
|
const getWeatherConfig: ToolConfig = {
|
|
15
23
|
id: "get-weather",
|
|
16
24
|
name: "Get Weather",
|
|
17
25
|
description: "Fetches current weather for a city",
|
|
18
26
|
input: z
|
|
19
27
|
.object({
|
|
28
|
+
locationName: z.string().describe("Location name"),
|
|
20
29
|
latitude: z.number().describe("Latitude coordinate"),
|
|
21
30
|
longitude: z.number().describe("Longitude coordinate"),
|
|
22
31
|
})
|
|
@@ -28,24 +37,43 @@ const getWeatherConfig: ToolConfig = {
|
|
|
28
37
|
})
|
|
29
38
|
.describe("Current weather information"),
|
|
30
39
|
pricing: { pricePerUse: 0, currency: "USD" },
|
|
31
|
-
handler: async ({ latitude, longitude }, agentInfo) => {
|
|
40
|
+
handler: async ({ locationName, latitude, longitude }, agentInfo, context) => {
|
|
32
41
|
console.log(
|
|
33
|
-
`User / Agent ${agentInfo.id} requested weather at ${latitude},${longitude}`
|
|
42
|
+
`User / Agent ${agentInfo.id} requested weather at ${locationName} (${latitude},${longitude})`
|
|
34
43
|
);
|
|
35
44
|
|
|
45
|
+
|
|
36
46
|
const response = await axios.get(
|
|
37
47
|
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,wind_speed_10m`
|
|
38
48
|
);
|
|
39
49
|
|
|
40
50
|
const { temperature_2m, wind_speed_10m } = response.data.current;
|
|
51
|
+
const weatherEmoji = getWeatherEmoji(temperature_2m);
|
|
41
52
|
|
|
42
53
|
return {
|
|
43
|
-
text: `The current temperature is ${temperature_2m}°C with wind speed of ${wind_speed_10m} km/h`,
|
|
54
|
+
text: `The current temperature in ${locationName} is ${temperature_2m}°C with wind speed of ${wind_speed_10m} km/h`,
|
|
44
55
|
data: {
|
|
45
56
|
temperature: temperature_2m,
|
|
46
57
|
windSpeed: wind_speed_10m,
|
|
47
58
|
},
|
|
48
|
-
ui:
|
|
59
|
+
ui: new CardUIBuilder()
|
|
60
|
+
.setRenderMode("page")
|
|
61
|
+
.title(`Current Weather in ${locationName} ${weatherEmoji}`)
|
|
62
|
+
.addChild(new MapUIBuilder()
|
|
63
|
+
.setInitialView(latitude, longitude, 10)
|
|
64
|
+
.setMapStyle('streets')
|
|
65
|
+
.addMarkers([
|
|
66
|
+
{
|
|
67
|
+
latitude,
|
|
68
|
+
longitude,
|
|
69
|
+
title: locationName,
|
|
70
|
+
description: `Temperature: ${temperature_2m}°C\nWind: ${wind_speed_10m} km/h`,
|
|
71
|
+
text: `${locationName} ${weatherEmoji}`,
|
|
72
|
+
}
|
|
73
|
+
])
|
|
74
|
+
.build())
|
|
75
|
+
.content(`Temperature: ${temperature_2m}°C\nWind Speed: ${wind_speed_10m} km/h`)
|
|
76
|
+
.build(),
|
|
49
77
|
};
|
|
50
78
|
},
|
|
51
79
|
};
|
|
@@ -56,6 +84,7 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
56
84
|
description: "Fetches hourly weather forecast",
|
|
57
85
|
input: z
|
|
58
86
|
.object({
|
|
87
|
+
locationName: z.string().describe("Location name"),
|
|
59
88
|
latitude: z.number().describe("Latitude coordinate"),
|
|
60
89
|
longitude: z.number().describe("Longitude coordinate"),
|
|
61
90
|
})
|
|
@@ -73,11 +102,35 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
73
102
|
})
|
|
74
103
|
.describe("Hourly weather forecast"),
|
|
75
104
|
pricing: { pricePerUse: 0, currency: "USD" },
|
|
76
|
-
handler: async ({ latitude, longitude }, agentInfo) => {
|
|
105
|
+
handler: async ({ locationName, latitude, longitude }, agentInfo, context) => {
|
|
77
106
|
console.log(
|
|
78
|
-
`User / Agent ${agentInfo.id} requested forecast at ${latitude},${longitude}`
|
|
107
|
+
`User / Agent ${agentInfo.id} requested forecast at ${locationName} (${latitude},${longitude})`
|
|
79
108
|
);
|
|
80
109
|
|
|
110
|
+
// Send early UI with map and loading state
|
|
111
|
+
if (context.updateUI) {
|
|
112
|
+
await context.updateUI({
|
|
113
|
+
ui: new CardUIBuilder()
|
|
114
|
+
.setRenderMode("page")
|
|
115
|
+
.title(`Weather Forecast for ${locationName} ⏳`)
|
|
116
|
+
.addChild(new MapUIBuilder()
|
|
117
|
+
.setInitialView(latitude, longitude, 10)
|
|
118
|
+
.setMapStyle('streets')
|
|
119
|
+
.addMarkers([
|
|
120
|
+
{
|
|
121
|
+
latitude,
|
|
122
|
+
longitude,
|
|
123
|
+
title: locationName,
|
|
124
|
+
description: 'Loading forecast data...',
|
|
125
|
+
text: `${locationName} ⏳`,
|
|
126
|
+
}
|
|
127
|
+
])
|
|
128
|
+
.build())
|
|
129
|
+
.content('Fetching weather forecast data...')
|
|
130
|
+
.build()
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
81
134
|
const response = await axios.get(
|
|
82
135
|
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m`
|
|
83
136
|
);
|
|
@@ -85,15 +138,53 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
85
138
|
const { time, temperature_2m, wind_speed_10m, relative_humidity_2m } =
|
|
86
139
|
response.data.hourly;
|
|
87
140
|
|
|
141
|
+
// Limit to first 24 hours of forecast data
|
|
142
|
+
const limitedTime = time.slice(0, 24);
|
|
143
|
+
const limitedTemp = temperature_2m.slice(0, 24);
|
|
144
|
+
const limitedWind = wind_speed_10m.slice(0, 24);
|
|
145
|
+
const limitedHumidity = relative_humidity_2m.slice(0, 24);
|
|
146
|
+
|
|
147
|
+
const weatherEmoji = getWeatherEmoji(limitedTemp[0]);
|
|
148
|
+
|
|
88
149
|
return {
|
|
89
|
-
text: `Weather forecast available for the next
|
|
150
|
+
text: `Weather forecast for ${locationName} available for the next 24 hours`,
|
|
90
151
|
data: {
|
|
91
|
-
times:
|
|
92
|
-
temperatures:
|
|
93
|
-
windSpeeds:
|
|
94
|
-
humidity:
|
|
152
|
+
times: limitedTime,
|
|
153
|
+
temperatures: limitedTemp,
|
|
154
|
+
windSpeeds: limitedWind,
|
|
155
|
+
humidity: limitedHumidity,
|
|
95
156
|
},
|
|
96
|
-
ui:
|
|
157
|
+
ui: new CardUIBuilder()
|
|
158
|
+
.setRenderMode("page")
|
|
159
|
+
.title(`Weather Forecast for ${locationName} ${weatherEmoji}`)
|
|
160
|
+
.addChild(new MapUIBuilder()
|
|
161
|
+
.setInitialView(latitude, longitude, 10)
|
|
162
|
+
.setMapStyle('streets')
|
|
163
|
+
.addMarkers([
|
|
164
|
+
{
|
|
165
|
+
latitude,
|
|
166
|
+
longitude,
|
|
167
|
+
title: locationName,
|
|
168
|
+
description: `Temperature: ${limitedTemp[0]}°C\nWind: ${limitedWind[0]} km/h`,
|
|
169
|
+
text: `${locationName} ${weatherEmoji}`,
|
|
170
|
+
}
|
|
171
|
+
])
|
|
172
|
+
.build())
|
|
173
|
+
.addChild(new TableUIBuilder()
|
|
174
|
+
.addColumns([
|
|
175
|
+
{ key: 'time', header: 'Time', type: 'string' },
|
|
176
|
+
{ key: 'temperature', header: 'Temperature (°C)', type: 'number' },
|
|
177
|
+
{ key: 'windSpeed', header: 'Wind Speed (km/h)', type: 'number' },
|
|
178
|
+
{ key: 'humidity', header: 'Humidity (%)', type: 'number' },
|
|
179
|
+
])
|
|
180
|
+
.rows(limitedTime.map((t: string, i: number) => ({
|
|
181
|
+
time: new Date(t).toLocaleString(),
|
|
182
|
+
temperature: limitedTemp[i],
|
|
183
|
+
windSpeed: limitedWind[i],
|
|
184
|
+
humidity: limitedHumidity[i],
|
|
185
|
+
})))
|
|
186
|
+
.build())
|
|
187
|
+
.build(),
|
|
97
188
|
};
|
|
98
189
|
},
|
|
99
190
|
};
|
|
@@ -106,8 +197,18 @@ const dainService = defineDAINService({
|
|
|
106
197
|
version: "1.0.0",
|
|
107
198
|
author: "Your Name",
|
|
108
199
|
tags: ["weather", "forecast", "dain"],
|
|
109
|
-
logo: "https://cdn-icons-png.flaticon.com/512/252/252035.png"
|
|
200
|
+
logo: "https://cdn-icons-png.flaticon.com/512/252/252035.png",
|
|
110
201
|
},
|
|
202
|
+
exampleQueries: [
|
|
203
|
+
{
|
|
204
|
+
category: "Weather",
|
|
205
|
+
queries: [
|
|
206
|
+
"What is the weather in Tokyo?",
|
|
207
|
+
"What is the weather in San Francisco?",
|
|
208
|
+
"What is the weather in London?",
|
|
209
|
+
],
|
|
210
|
+
}
|
|
211
|
+
],
|
|
111
212
|
identity: {
|
|
112
213
|
apiKey: process.env.DAIN_API_KEY,
|
|
113
214
|
},
|
package/package.json
CHANGED
|
@@ -6,17 +6,26 @@ import axios from "axios";
|
|
|
6
6
|
import {
|
|
7
7
|
defineDAINService,
|
|
8
8
|
ToolConfig,
|
|
9
|
-
ServiceConfig,
|
|
10
|
-
ToolboxConfig,
|
|
11
|
-
ServiceContext,
|
|
12
9
|
} from "@dainprotocol/service-sdk";
|
|
13
10
|
|
|
11
|
+
import { CardUIBuilder, TableUIBuilder, MapUIBuilder } from "@dainprotocol/utils";
|
|
12
|
+
|
|
13
|
+
const getWeatherEmoji = (temperature: number): string => {
|
|
14
|
+
if (temperature <= 0) return '🥶';
|
|
15
|
+
if (temperature <= 10) return '❄️';
|
|
16
|
+
if (temperature <= 20) return '⛅';
|
|
17
|
+
if (temperature <= 25) return '☀️';
|
|
18
|
+
if (temperature <= 30) return '🌞';
|
|
19
|
+
return '🔥';
|
|
20
|
+
};
|
|
21
|
+
|
|
14
22
|
const getWeatherConfig: ToolConfig = {
|
|
15
23
|
id: "get-weather",
|
|
16
24
|
name: "Get Weather",
|
|
17
25
|
description: "Fetches current weather for a city",
|
|
18
26
|
input: z
|
|
19
27
|
.object({
|
|
28
|
+
locationName: z.string().describe("Location name"),
|
|
20
29
|
latitude: z.number().describe("Latitude coordinate"),
|
|
21
30
|
longitude: z.number().describe("Longitude coordinate"),
|
|
22
31
|
})
|
|
@@ -28,24 +37,43 @@ const getWeatherConfig: ToolConfig = {
|
|
|
28
37
|
})
|
|
29
38
|
.describe("Current weather information"),
|
|
30
39
|
pricing: { pricePerUse: 0, currency: "USD" },
|
|
31
|
-
handler: async ({ latitude, longitude }, agentInfo) => {
|
|
40
|
+
handler: async ({ locationName, latitude, longitude }, agentInfo, context) => {
|
|
32
41
|
console.log(
|
|
33
|
-
`User / Agent ${agentInfo.id} requested weather at ${latitude},${longitude}`
|
|
42
|
+
`User / Agent ${agentInfo.id} requested weather at ${locationName} (${latitude},${longitude})`
|
|
34
43
|
);
|
|
35
44
|
|
|
45
|
+
|
|
36
46
|
const response = await axios.get(
|
|
37
47
|
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,wind_speed_10m`
|
|
38
48
|
);
|
|
39
49
|
|
|
40
50
|
const { temperature_2m, wind_speed_10m } = response.data.current;
|
|
51
|
+
const weatherEmoji = getWeatherEmoji(temperature_2m);
|
|
41
52
|
|
|
42
53
|
return {
|
|
43
|
-
text: `The current temperature is ${temperature_2m}°C with wind speed of ${wind_speed_10m} km/h`,
|
|
54
|
+
text: `The current temperature in ${locationName} is ${temperature_2m}°C with wind speed of ${wind_speed_10m} km/h`,
|
|
44
55
|
data: {
|
|
45
56
|
temperature: temperature_2m,
|
|
46
57
|
windSpeed: wind_speed_10m,
|
|
47
58
|
},
|
|
48
|
-
ui:
|
|
59
|
+
ui: new CardUIBuilder()
|
|
60
|
+
.setRenderMode("page")
|
|
61
|
+
.title(`Current Weather in ${locationName} ${weatherEmoji}`)
|
|
62
|
+
.addChild(new MapUIBuilder()
|
|
63
|
+
.setInitialView(latitude, longitude, 10)
|
|
64
|
+
.setMapStyle('streets')
|
|
65
|
+
.addMarkers([
|
|
66
|
+
{
|
|
67
|
+
latitude,
|
|
68
|
+
longitude,
|
|
69
|
+
title: locationName,
|
|
70
|
+
description: `Temperature: ${temperature_2m}°C\nWind: ${wind_speed_10m} km/h`,
|
|
71
|
+
text: `${locationName} ${weatherEmoji}`,
|
|
72
|
+
}
|
|
73
|
+
])
|
|
74
|
+
.build())
|
|
75
|
+
.content(`Temperature: ${temperature_2m}°C\nWind Speed: ${wind_speed_10m} km/h`)
|
|
76
|
+
.build(),
|
|
49
77
|
};
|
|
50
78
|
},
|
|
51
79
|
};
|
|
@@ -56,6 +84,7 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
56
84
|
description: "Fetches hourly weather forecast",
|
|
57
85
|
input: z
|
|
58
86
|
.object({
|
|
87
|
+
locationName: z.string().describe("Location name"),
|
|
59
88
|
latitude: z.number().describe("Latitude coordinate"),
|
|
60
89
|
longitude: z.number().describe("Longitude coordinate"),
|
|
61
90
|
})
|
|
@@ -73,11 +102,35 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
73
102
|
})
|
|
74
103
|
.describe("Hourly weather forecast"),
|
|
75
104
|
pricing: { pricePerUse: 0, currency: "USD" },
|
|
76
|
-
handler: async ({ latitude, longitude }, agentInfo) => {
|
|
105
|
+
handler: async ({ locationName, latitude, longitude }, agentInfo, context) => {
|
|
77
106
|
console.log(
|
|
78
|
-
`User / Agent ${agentInfo.id} requested forecast at ${latitude},${longitude}`
|
|
107
|
+
`User / Agent ${agentInfo.id} requested forecast at ${locationName} (${latitude},${longitude})`
|
|
79
108
|
);
|
|
80
109
|
|
|
110
|
+
// Send early UI with map and loading state
|
|
111
|
+
if (context.updateUI) {
|
|
112
|
+
await context.updateUI({
|
|
113
|
+
ui: new CardUIBuilder()
|
|
114
|
+
.setRenderMode("page")
|
|
115
|
+
.title(`Weather Forecast for ${locationName} ⏳`)
|
|
116
|
+
.addChild(new MapUIBuilder()
|
|
117
|
+
.setInitialView(latitude, longitude, 10)
|
|
118
|
+
.setMapStyle('streets')
|
|
119
|
+
.addMarkers([
|
|
120
|
+
{
|
|
121
|
+
latitude,
|
|
122
|
+
longitude,
|
|
123
|
+
title: locationName,
|
|
124
|
+
description: 'Loading forecast data...',
|
|
125
|
+
text: `${locationName} ⏳`,
|
|
126
|
+
}
|
|
127
|
+
])
|
|
128
|
+
.build())
|
|
129
|
+
.content('Fetching weather forecast data...')
|
|
130
|
+
.build()
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
81
134
|
const response = await axios.get(
|
|
82
135
|
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m`
|
|
83
136
|
);
|
|
@@ -85,15 +138,53 @@ const getWeatherForecastConfig: ToolConfig = {
|
|
|
85
138
|
const { time, temperature_2m, wind_speed_10m, relative_humidity_2m } =
|
|
86
139
|
response.data.hourly;
|
|
87
140
|
|
|
141
|
+
// Limit to first 24 hours of forecast data
|
|
142
|
+
const limitedTime = time.slice(0, 24);
|
|
143
|
+
const limitedTemp = temperature_2m.slice(0, 24);
|
|
144
|
+
const limitedWind = wind_speed_10m.slice(0, 24);
|
|
145
|
+
const limitedHumidity = relative_humidity_2m.slice(0, 24);
|
|
146
|
+
|
|
147
|
+
const weatherEmoji = getWeatherEmoji(limitedTemp[0]);
|
|
148
|
+
|
|
88
149
|
return {
|
|
89
|
-
text: `Weather forecast available for the next
|
|
150
|
+
text: `Weather forecast for ${locationName} available for the next 24 hours`,
|
|
90
151
|
data: {
|
|
91
|
-
times:
|
|
92
|
-
temperatures:
|
|
93
|
-
windSpeeds:
|
|
94
|
-
humidity:
|
|
152
|
+
times: limitedTime,
|
|
153
|
+
temperatures: limitedTemp,
|
|
154
|
+
windSpeeds: limitedWind,
|
|
155
|
+
humidity: limitedHumidity,
|
|
95
156
|
},
|
|
96
|
-
ui:
|
|
157
|
+
ui: new CardUIBuilder()
|
|
158
|
+
.setRenderMode("page")
|
|
159
|
+
.title(`Weather Forecast for ${locationName} ${weatherEmoji}`)
|
|
160
|
+
.addChild(new MapUIBuilder()
|
|
161
|
+
.setInitialView(latitude, longitude, 10)
|
|
162
|
+
.setMapStyle('streets')
|
|
163
|
+
.addMarkers([
|
|
164
|
+
{
|
|
165
|
+
latitude,
|
|
166
|
+
longitude,
|
|
167
|
+
title: locationName,
|
|
168
|
+
description: `Temperature: ${limitedTemp[0]}°C\nWind: ${limitedWind[0]} km/h`,
|
|
169
|
+
text: `${locationName} ${weatherEmoji}`,
|
|
170
|
+
}
|
|
171
|
+
])
|
|
172
|
+
.build())
|
|
173
|
+
.addChild(new TableUIBuilder()
|
|
174
|
+
.addColumns([
|
|
175
|
+
{ key: 'time', header: 'Time', type: 'string' },
|
|
176
|
+
{ key: 'temperature', header: 'Temperature (°C)', type: 'number' },
|
|
177
|
+
{ key: 'windSpeed', header: 'Wind Speed (km/h)', type: 'number' },
|
|
178
|
+
{ key: 'humidity', header: 'Humidity (%)', type: 'number' },
|
|
179
|
+
])
|
|
180
|
+
.rows(limitedTime.map((t: string, i: number) => ({
|
|
181
|
+
time: new Date(t).toLocaleString(),
|
|
182
|
+
temperature: limitedTemp[i],
|
|
183
|
+
windSpeed: limitedWind[i],
|
|
184
|
+
humidity: limitedHumidity[i],
|
|
185
|
+
})))
|
|
186
|
+
.build())
|
|
187
|
+
.build(),
|
|
97
188
|
};
|
|
98
189
|
},
|
|
99
190
|
};
|
|
@@ -106,8 +197,18 @@ const dainService = defineDAINService({
|
|
|
106
197
|
version: "1.0.0",
|
|
107
198
|
author: "Your Name",
|
|
108
199
|
tags: ["weather", "forecast", "dain"],
|
|
109
|
-
logo: "https://cdn-icons-png.flaticon.com/512/252/252035.png"
|
|
200
|
+
logo: "https://cdn-icons-png.flaticon.com/512/252/252035.png",
|
|
110
201
|
},
|
|
202
|
+
exampleQueries: [
|
|
203
|
+
{
|
|
204
|
+
category: "Weather",
|
|
205
|
+
queries: [
|
|
206
|
+
"What is the weather in Tokyo?",
|
|
207
|
+
"What is the weather in San Francisco?",
|
|
208
|
+
"What is the weather in London?",
|
|
209
|
+
],
|
|
210
|
+
}
|
|
211
|
+
],
|
|
111
212
|
identity: {
|
|
112
213
|
apiKey: process.env.DAIN_API_KEY,
|
|
113
214
|
},
|