feat: weather_map_screenshot에 JMA(RSMC 도쿄) 태풍 전체 진로도 추가

KMA는 한국에 영향 줄 태풍만, NHC는 대서양/동태평양만 보여줘서 대만·필리핀·
괌·일본 근해에 있지만 아직 한국 영향권 밖인 태풍은 두 소스 모두에서 안 보임.
JMA(서태평양 전역 담당 지역특별기상센터)의 typhoon=all 지도를 캡처 대상에
추가해 그 사각지대를 메움.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
kim
2026-08-07 13:16:13 +09:00
co-authored by Claude Sonnet 5
parent d51c40484a
commit 9e0520d069
+16 -5
View File
@@ -1603,18 +1603,26 @@ const KMA_TYPHOON_TRACK_URL = 'https://www.weather.go.kr/w/typhoon/ko/weather/ty
// string like KMA's — nhc_active_storms resolves the right one, this just validates the
// shape stays within nhc.noaa.gov's own graphics pages (no arbitrary path/host).
const NHC_TRACK_URL_RE = /^https:\/\/www\.nhc\.noaa\.gov\/graphics_[a-z]+\d\.shtml(?:\?.*)?$/;
// JMA (RSMC Tokyo) is the actual regional warning center for the WHOLE Western North
// Pacific basin — unlike KMA's page (only shows the storm KMA itself has designated,
// i.e. ones close enough to threaten Korea) and NHC's page (Atlantic/EPac/CPac only).
// A typhoon sitting near Taiwan/Philippines/Guam/Japan with no Korea impact yet is
// invisible to both, so this plugs that gap. typhoon=all draws every active WNP storm's
// forecast track at once — no per-storm slot lookup needed, so (like KMA) this is a
// single fixed URL rather than something resolved per-storm.
const JMA_TYPHOON_MAP_URL = 'https://www.jma.go.jp/bosai/map.html#4/17.686/133.792/&elem=root&typhoon=all&contents=typhoon';
export const weatherMapScreenshotTool = {
name: 'weather_map_screenshot',
description: 'Capture a real screenshot of a rendered weather map — the Windy embed (radar, satellite, wind, precipitation, etc.), the KMA typhoon forecast-track page, or an NHC forecast-track page (from nhc_active_storms) — so you can actually SEE it before describing it. Call this with the exact URL you just generated — do not guess what the map shows from the URL parameters alone.',
description: 'Capture a real screenshot of a rendered weather map — the Windy embed (radar, satellite, wind, precipitation, etc.), the KMA typhoon forecast-track page, the JMA (RSMC Tokyo) all-active-typhoons forecast-track map, or an NHC forecast-track page (from nhc_active_storms) — so you can actually SEE it before describing it. Call this with the exact URL you just generated — do not guess what the map shows from the URL parameters alone.',
schema: {
url: `The exact https://embed.windy.com/embed2.html?... URL, the literal ${KMA_TYPHOON_TRACK_URL} for KMA, or an https://www.nhc.noaa.gov/graphics_XXN.shtml URL from nhc_active_storms`,
url: `The exact https://embed.windy.com/embed2.html?... URL, the literal ${KMA_TYPHOON_TRACK_URL} for KMA, the literal ${JMA_TYPHOON_MAP_URL} for JMA, or an https://www.nhc.noaa.gov/graphics_XXN.shtml URL from nhc_active_storms`,
wait_ms: 'Milliseconds to wait for map tiles to finish loading before capturing (default 4000, max 8000)',
},
jsonSchema: {
type: 'object',
properties: {
url: { type: 'string', description: 'The exact embed.windy.com, KMA typhoon track, or NHC graphics_XXN.shtml URL to capture' },
url: { type: 'string', description: 'The exact embed.windy.com, KMA typhoon track, JMA typhoon track, or NHC graphics_XXN.shtml URL to capture' },
wait_ms: { type: 'number', description: 'Wait time in ms for tiles to load (default 4000, max 8000)' },
},
required: ['url'],
@@ -1627,9 +1635,10 @@ export const weatherMapScreenshotTool = {
let parsed: URL;
try { parsed = new URL(urlStr); } catch { return { success: false, error: 'Invalid URL' }; }
const isKmaTrack = urlStr === KMA_TYPHOON_TRACK_URL;
const isJmaTrack = urlStr === JMA_TYPHOON_MAP_URL;
const isNhcTrack = NHC_TRACK_URL_RE.test(urlStr);
if (parsed.hostname !== 'embed.windy.com' && !isKmaTrack && !isNhcTrack) {
return { success: false, error: `Only embed.windy.com, ${KMA_TYPHOON_TRACK_URL}, or nhc.noaa.gov graphics_XXN.shtml URLs can be captured` };
if (parsed.hostname !== 'embed.windy.com' && !isKmaTrack && !isJmaTrack && !isNhcTrack) {
return { success: false, error: `Only embed.windy.com, ${KMA_TYPHOON_TRACK_URL}, ${JMA_TYPHOON_MAP_URL}, or nhc.noaa.gov graphics_XXN.shtml URLs can be captured` };
}
const waitMs = Math.min(Math.max(Number(args?.wait_ms) || 4000, 1000), 8000);
@@ -1657,6 +1666,8 @@ export const weatherMapScreenshotTool = {
const label = isKmaTrack
? 'KMA 태풍 예상진로 페이지 캡처 완료'
: isJmaTrack
? 'JMA(RSMC 도쿄) 태풍 예상진로 지도 캡처 완료'
: isNhcTrack
? 'NHC 허리케인 예상진로 페이지 캡처 완료'
: `Windy 지도 캡처 완료 (overlay=${parsed.searchParams.get('overlay') || 'map'}, zoom=${parsed.searchParams.get('zoom') || '?'})`;