Unknown sites: ReadPage extracts main content (readabilityMode: article), returns raw text with extraction hint → parseMode: "raw", agent (LLM) interprets directly
Output Field
Description
parseMode
"structured" (parsed JSON) or "raw" (text for agent)
weather
Weather condition (sunny, cloudy, rain, etc.)
temperature
Temperature range
windSpeed
Wind speed/level
windDirection
Wind direction
Environment Configuration
Pre-check: ALIYUN_IQS_API_KEY Required
bash
if [ -z "$ALIYUN_IQS_API_KEY" ]; then echo "API Key 未配置"; else echo "API Key 已配置(已脱敏)"; fi
If output is 'API Key 未配置', the API Key is not configured.
weather.com.cn (China Weather Network, all other subdomains) — parseWeatherComCn → readabilityMode: normal
Other sites — no parser, return raw text → readabilityMode: article (cleaner body extraction)
Error Handling
Error Code
Description
Solution
CREDENTIALS_MISSING
API Key not configured
Set ALIYUN_IQS_API_KEY environment variable
NO_RESULTS
No weather results found
Check city name is correct
QUERY_FAILED
API call failed
Check network, verify credentials
PARSE_FAILED
Failed to parse weather data from webpage
The target site's page structure may have changed; update the corresponding parser or add a new one (see Extending section)
Best Practices
Use Chinese city names for domestic weather queries for better accuracy
Node.js >= 18 required - native fetch API is used, no npm install needed
Cache awareness - ReadPage uses maxAge not set, always fetches latest data
Extensible parsers - Each weather site has its own parser; add new sites by registering in PARSER_REGISTRY
Continuous Evolution
This skill is designed to self-improve over time. When the script encounters an unknown site format (no matching parser), it returns parseMode: "raw" with an evolveHint field.
Agent behavior when parseMode is "raw":
First: Answer the user — Extract weather info from rawText using LLM understanding and respond to the user immediately.
Then: Evolve — Read the evolveHint and analyze the rawText format pattern, then write a new parser function and register it in PARSER_REGISTRY (see Extending section below). This ensures that next time the same site format is hit, it goes through structured mode directly.
text
First query for unknown site:
search → readpage → no parser match → raw mode → agent answers user
→ agent writes new parser ← evolveHint
Subsequent queries for same site:
search → readpage → parser match → structured mode → direct JSON output
Key: The skill gets smarter with every new city searched. Each raw-mode encounter is an opportunity to add a new parser, progressively covering more site formats.
Extending: Add a New Weather Site Parser
The script uses a Parser Registry pattern. Each weather site has its own dedicated parser function, and the router automatically dispatches based on URL. To add support for a new site, follow these 3 steps:
Step 1: Write a Parser Function
Add a new parser function in scripts/weather.mjs. It must accept (content, city) and return the standard format:
javascript
function parseMyNewSite(content, city) {
const forecast = [];
// Parse the text content from ReadPage for this specific site
// Extract: date, weather, temperature, windDirection, windSpeed
// ...your parsing logic here...
return {
city,
queryTime: new Date().toISOString(),
forecastDays: Math.min(forecast.length, 7),
forecast: forecast.slice(0, 7),
raw: forecast.length === 0 ? content.substring(0, 2000) : undefined,
};
}
Return format for each forecast item:
Field
Type
Example
date
string
"04/07 星期二"
weather
string
"晴转多云"
temperature
string
"5°C ~ 18°C"
windDirection
string
"北风"
windSpeed
string
"3-4级"
Step 2: Register in PARSER_REGISTRY
Add your parser to the registry array at the top of weather.mjs. Order matters — higher position = higher priority:
parseWeatherData(content, city, url)
│
├─ URL contains "weather.cma.cn"? → parseCmaWeather(content, city)
├─ URL contains "baidu.weather.com.cn"? → parseBaiduWeatherComCn(content, city)
├─ URL contains "sq.weather.com.cn"? → parseBaiduWeatherComCn(content, city)
├─ URL contains "weather.com.cn"? → parseWeatherComCn(content, city)
├─ URL contains "mynewsite.com"? → parseMyNewSite(content, city)
│
└─ No match or result < 3 days? → return rawText + hint (agent interprets)
Tip: Use node -e "..." with the ReadPage API to fetch and inspect the raw text format of a new site before writing the parser. See existing parsers (parseCmaWeather, parseWeatherComCn) as reference implementations.