fix: concise Korean weather reply (current conditions, one sentence)
getWeather returned a verbose multi-section English forecast that the 3B re-synthesised into long, CJK/°F-leaking answers. Hand it a ready-to-speak Korean one-liner (지금 <곳> 날씨는 <상태>, 기온 N도(체감 M도)입니다) and drop the hourly/7-day firehose from the default voice reply.
This commit is contained in:
@@ -175,6 +175,20 @@ WMO_CODES = {
|
||||
99: "Thunderstorm with heavy hail",
|
||||
}
|
||||
|
||||
# Korean conditions for the concise spoken reply.
|
||||
WMO_CODES_KO = {
|
||||
0: "맑음", 1: "대체로 맑음", 2: "구름 조금", 3: "흐림",
|
||||
45: "안개", 48: "서리 안개",
|
||||
51: "약한 이슬비", 53: "이슬비", 55: "강한 이슬비",
|
||||
56: "약한 어는 이슬비", 57: "강한 어는 이슬비",
|
||||
61: "약한 비", 63: "비", 65: "강한 비",
|
||||
66: "약한 어는 비", 67: "강한 어는 비",
|
||||
71: "약한 눈", 73: "눈", 75: "강한 눈", 77: "싸락눈",
|
||||
80: "약한 소나기", 81: "소나기", 82: "강한 소나기",
|
||||
85: "약한 눈소나기", 86: "강한 눈소나기",
|
||||
95: "천둥번개", 96: "우박 동반 천둥번개", 99: "강한 우박 천둥번개",
|
||||
}
|
||||
|
||||
|
||||
class WeatherTool(Tool):
|
||||
"""Tool for getting current weather using Open-Meteo API."""
|
||||
@@ -412,71 +426,31 @@ class WeatherTool(Tool):
|
||||
# Get weather description
|
||||
weather_desc = WMO_CODES.get(weather_code, "Unknown conditions")
|
||||
|
||||
# Build response text — current conditions
|
||||
lines = [
|
||||
f"Current weather in {location_display}:",
|
||||
f"",
|
||||
f"Conditions: {weather_desc}",
|
||||
]
|
||||
|
||||
# Concise, ready-to-speak Korean one-liner for the voice path. The
|
||||
# tool result is normally re-synthesised by the LLM, but a small
|
||||
# model rambles and leaks °F / CJK fragments, so we hand it a clean
|
||||
# Korean sentence it can echo verbatim (one-sentence system rule).
|
||||
_ko = WMO_CODES_KO.get(weather_code, weather_desc)
|
||||
_short_loc = location_display.split(",")[0].strip() or location_display
|
||||
_ko_parts = [f"지금 {_short_loc} 날씨는 {_ko}"]
|
||||
if temp_c is not None:
|
||||
lines.append(f"Temperature: {temp_c}°C ({temp_f}°F)")
|
||||
_t = f"기온 {round(temp_c)}도"
|
||||
if feels_like_c is not None and round(feels_like_c) != round(temp_c):
|
||||
_t += f"(체감 {round(feels_like_c)}도)"
|
||||
_ko_parts.append(_t)
|
||||
ko_sentence = ", ".join(_ko_parts) + "입니다."
|
||||
|
||||
if feels_like_c is not None and feels_like_c != temp_c:
|
||||
lines.append(f"Feels like: {feels_like_c}°C ({feels_like_f}°F)")
|
||||
|
||||
if humidity is not None:
|
||||
lines.append(f"Humidity: {humidity}%")
|
||||
|
||||
if wind_speed is not None:
|
||||
wind_info = f"Wind: {wind_speed} km/h"
|
||||
if wind_gusts and wind_gusts > wind_speed:
|
||||
wind_info += f" (gusts up to {wind_gusts} km/h)"
|
||||
lines.append(wind_info)
|
||||
|
||||
# Append today's hourly forecast (remaining hours)
|
||||
hourly = weather_data.get("hourly", {})
|
||||
hourly_times = hourly.get("time", [])
|
||||
hourly_temps = hourly.get("temperature_2m", [])
|
||||
hourly_codes = hourly.get("weather_code", [])
|
||||
|
||||
if hourly_times and hourly_temps:
|
||||
# Get current hour from the current time field
|
||||
current_time = current.get("time", "")
|
||||
current_hour_str = current_time[11:13] if len(current_time) >= 13 else ""
|
||||
current_hour = int(current_hour_str) if current_hour_str.isdigit() else 0
|
||||
today_prefix = current_time[:10] if len(current_time) >= 10 else ""
|
||||
|
||||
hourly_lines = []
|
||||
for i, t in enumerate(hourly_times):
|
||||
if not t.startswith(today_prefix):
|
||||
continue
|
||||
hour_str = t[11:13] if len(t) >= 13 else ""
|
||||
hour = int(hour_str) if hour_str.isdigit() else -1
|
||||
# Show every 3 hours from now onwards
|
||||
if hour > current_hour and hour % 3 == 0 and i < len(hourly_temps) and i < len(hourly_codes):
|
||||
desc = WMO_CODES.get(hourly_codes[i], "")
|
||||
hourly_lines.append(f" {hour:02d}:00 — {hourly_temps[i]}°C, {desc}")
|
||||
|
||||
if hourly_lines:
|
||||
lines.append("")
|
||||
lines.append("Today's forecast (upcoming hours):")
|
||||
lines.extend(hourly_lines)
|
||||
|
||||
# Append daily forecast
|
||||
daily = weather_data.get("daily", {})
|
||||
daily_dates = daily.get("time", [])
|
||||
daily_codes = daily.get("weather_code", [])
|
||||
daily_max = daily.get("temperature_2m_max", [])
|
||||
daily_min = daily.get("temperature_2m_min", [])
|
||||
|
||||
if daily_dates and daily_max and daily_min:
|
||||
lines.append("")
|
||||
lines.append("7-day forecast:")
|
||||
for i, date_str in enumerate(daily_dates):
|
||||
if i < len(daily_max) and i < len(daily_min) and i < len(daily_codes):
|
||||
desc = WMO_CODES.get(daily_codes[i], "")
|
||||
lines.append(f" {date_str}: {daily_min[i]}–{daily_max[i]}°C, {desc}")
|
||||
# Build response text — concise current conditions (Korean sentence
|
||||
# first so the model echoes it; English detail kept for any follow-up
|
||||
# reasoning but the forecast firehose is dropped to curb rambling).
|
||||
lines = [
|
||||
f"한국어로 정확히 이 한 문장만 답하세요: {ko_sentence}",
|
||||
f"(참고 데이터 — 답변에 추가하지 말 것: {location_display}, {weather_desc}, "
|
||||
f"{temp_c}°C feels {feels_like_c}°C, humidity {humidity}%, wind {wind_speed}km/h)",
|
||||
]
|
||||
# Forecast (hourly / 7-day) is intentionally omitted from the default
|
||||
# voice reply to keep it to one spoken sentence; current conditions
|
||||
# are what "날씨 알려줘" asks for.
|
||||
|
||||
reply_text = "\n".join(lines)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user