iobroker.assistant 1.0.3 → 1.2.0

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.
Files changed (73) hide show
  1. package/README.md +65 -0
  2. package/admin/custom/.vite/manifest.json +62 -62
  3. package/admin/custom/assets/Components-BSewCBfS.js +2 -0
  4. package/admin/custom/assets/{_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1-A4gakomR.js → _virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1-C5NPM0Of.js} +1 -1
  5. package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-CwqmfMvn.js → _virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-IaosaymG.js} +1 -1
  6. package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-BMuLYe6f.js → _virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-Cdyjt5KT.js} +39 -39
  7. package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__loadShare__shared-BxjZmnpc.js → _virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__loadShare__shared-Dsw5zWS8.js} +1 -1
  8. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__prebuild___mf_0_iobroker_mf_1_json_mf_2_config__prebuild__-SgSagTOv.js +122 -0
  9. package/admin/custom/assets/{hostInit-4roC4hEj.js → hostInit-jJe8bIfV.js} +1 -1
  10. package/admin/custom/assets/{lib-CchzgTUs.js → lib-CL8mXvI6.js} +1 -1
  11. package/admin/custom/assets/{mf-entry-bootstrap-0-4806bbe4.js → mf-entry-bootstrap-0-ab227aa6.js} +2 -2
  12. package/admin/custom/assets/{pendingShares-DLlv8yFY.js → pendingShares-wrGtfliQ.js} +1 -1
  13. package/admin/custom/customComponents.js +2 -2
  14. package/admin/custom/i18n/de.json +40 -0
  15. package/admin/custom/i18n/en.json +40 -0
  16. package/admin/custom/i18n/es.json +40 -0
  17. package/admin/custom/i18n/fr.json +40 -0
  18. package/admin/custom/i18n/it.json +40 -0
  19. package/admin/custom/i18n/nl.json +40 -0
  20. package/admin/custom/i18n/pl.json +40 -0
  21. package/admin/custom/i18n/pt.json +40 -0
  22. package/admin/custom/i18n/ru.json +40 -0
  23. package/admin/custom/i18n/uk.json +40 -0
  24. package/admin/custom/i18n/zh-cn.json +40 -0
  25. package/admin/custom/index.html +2 -2
  26. package/admin/custom/mf-manifest.json +1 -1
  27. package/admin/custom/mf-stats.json +1 -1
  28. package/admin/i18n/de.json +13 -3
  29. package/admin/i18n/en.json +13 -3
  30. package/admin/i18n/es.json +13 -3
  31. package/admin/i18n/fr.json +13 -3
  32. package/admin/i18n/it.json +13 -3
  33. package/admin/i18n/nl.json +13 -3
  34. package/admin/i18n/pl.json +13 -3
  35. package/admin/i18n/pt.json +13 -3
  36. package/admin/i18n/ru.json +13 -3
  37. package/admin/i18n/uk.json +13 -3
  38. package/admin/i18n/zh-cn.json +13 -3
  39. package/admin/jsonConfig.json +61 -2
  40. package/build/lib/journal.js +298 -2
  41. package/build/lib/journal.js.map +1 -1
  42. package/build/lib/llm.js +105 -4
  43. package/build/lib/llm.js.map +1 -1
  44. package/build/lib/localLlm.js +47 -10
  45. package/build/lib/localLlm.js.map +1 -1
  46. package/build/lib/nlu.js +124 -5
  47. package/build/lib/nlu.js.map +1 -1
  48. package/build/lib/tools.js +3 -0
  49. package/build/lib/tools.js.map +1 -1
  50. package/build/lib/voice/esphome.js +81 -7
  51. package/build/lib/voice/esphome.js.map +1 -1
  52. package/build/lib/voice/esphomeProto.js.map +1 -1
  53. package/build/lib/voice/mediaServer.js +29 -1
  54. package/build/lib/voice/mediaServer.js.map +1 -1
  55. package/build/lib/voice/protocol.js.map +1 -1
  56. package/build/lib/voice/voiceServer.js +81 -7
  57. package/build/lib/voice/voiceServer.js.map +1 -1
  58. package/build/lib/voice/wakeWords.js +284 -0
  59. package/build/lib/voice/wakeWords.js.map +1 -0
  60. package/build/lib/voice/wyoming.js +12 -4
  61. package/build/lib/voice/wyoming.js.map +1 -1
  62. package/build/lib/weather.js +160 -0
  63. package/build/lib/weather.js.map +1 -1
  64. package/build/lib/youtube.js +625 -0
  65. package/build/lib/youtube.js.map +1 -0
  66. package/build/main.js +1152 -76
  67. package/build/main.js.map +1 -1
  68. package/io-package.json +30 -14
  69. package/package.json +6 -6
  70. package/admin/custom/assets/Components-C6qcpaRC.js +0 -1
  71. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__prebuild___mf_0_iobroker_mf_1_json_mf_2_config__prebuild__-TM4l0OYm.js +0 -122
  72. /package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-BkH7fzDw.js → _virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-BkH7fzDw.js} +0 -0
  73. /package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__201375093093590__prebuild__react_mf_1_jsx_mf_2_runtime__prebuild__-M61rjtmp.js → _virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__163539842885036__prebuild__react_mf_1_jsx_mf_2_runtime__prebuild__-M61rjtmp.js} +0 -0
@@ -17,6 +17,7 @@ exports.wmoText = wmoText;
17
17
  exports.buildWeatherReport = buildWeatherReport;
18
18
  exports.trimReport = trimReport;
19
19
  exports.buildWeatherPrompt = buildWeatherPrompt;
20
+ exports.buildWeatherAnswer = buildWeatherAnswer;
20
21
  /**
21
22
  * Registry of weather adapters offered in the settings dropdown. `kind` present = fully normalized.
22
23
  * `perLocationProbe` (a state path that exists once per location) marks adapters that namespace their data
@@ -552,4 +553,163 @@ function buildWeatherPrompt(report, lang) {
552
553
  lines.push(t.hint);
553
554
  return lines.join('\n');
554
555
  }
556
+ /** WMO texts in the other voice languages, by the English text {@link wmoText} puts into a report. */
557
+ const WMO_LOCAL = {
558
+ de: {
559
+ 'clear sky': 'klarer Himmel',
560
+ 'mainly clear': 'überwiegend klar',
561
+ 'partly cloudy': 'teilweise bewölkt',
562
+ overcast: 'bedeckt',
563
+ fog: 'Nebel',
564
+ 'depositing rime fog': 'Nebel mit Raureif',
565
+ 'light drizzle': 'leichter Nieselregen',
566
+ drizzle: 'Nieselregen',
567
+ 'dense drizzle': 'starker Nieselregen',
568
+ 'freezing drizzle': 'gefrierender Nieselregen',
569
+ 'dense freezing drizzle': 'starker gefrierender Nieselregen',
570
+ 'slight rain': 'leichter Regen',
571
+ rain: 'Regen',
572
+ 'heavy rain': 'starker Regen',
573
+ 'freezing rain': 'gefrierender Regen',
574
+ 'heavy freezing rain': 'starker gefrierender Regen',
575
+ 'slight snow': 'leichter Schneefall',
576
+ snow: 'Schneefall',
577
+ 'heavy snow': 'starker Schneefall',
578
+ 'snow grains': 'Schneegriesel',
579
+ 'slight rain showers': 'leichte Regenschauer',
580
+ 'rain showers': 'Regenschauer',
581
+ 'violent rain showers': 'heftige Regenschauer',
582
+ 'snow showers': 'Schneeschauer',
583
+ 'heavy snow showers': 'starke Schneeschauer',
584
+ thunderstorm: 'Gewitter',
585
+ 'thunderstorm with slight hail': 'Gewitter mit leichtem Hagel',
586
+ 'thunderstorm with heavy hail': 'Gewitter mit starkem Hagel',
587
+ },
588
+ ru: {
589
+ 'clear sky': 'ясно',
590
+ 'mainly clear': 'преимущественно ясно',
591
+ 'partly cloudy': 'переменная облачность',
592
+ overcast: 'пасмурно',
593
+ fog: 'туман',
594
+ 'depositing rime fog': 'туман с изморозью',
595
+ 'light drizzle': 'лёгкая морось',
596
+ drizzle: 'морось',
597
+ 'dense drizzle': 'сильная морось',
598
+ 'freezing drizzle': 'ледяная морось',
599
+ 'dense freezing drizzle': 'сильная ледяная морось',
600
+ 'slight rain': 'небольшой дождь',
601
+ rain: 'дождь',
602
+ 'heavy rain': 'сильный дождь',
603
+ 'freezing rain': 'ледяной дождь',
604
+ 'heavy freezing rain': 'сильный ледяной дождь',
605
+ 'slight snow': 'небольшой снег',
606
+ snow: 'снег',
607
+ 'heavy snow': 'сильный снег',
608
+ 'snow grains': 'снежная крупа',
609
+ 'slight rain showers': 'небольшой ливень',
610
+ 'rain showers': 'ливень',
611
+ 'violent rain showers': 'сильный ливень',
612
+ 'snow showers': 'снегопад',
613
+ 'heavy snow showers': 'сильный снегопад',
614
+ thunderstorm: 'гроза',
615
+ 'thunderstorm with slight hail': 'гроза с небольшим градом',
616
+ 'thunderstorm with heavy hail': 'гроза с сильным градом',
617
+ },
618
+ };
619
+ /** Russian noun form after a number: 1 градус, 2 градуса, 5 градусов. */
620
+ function ruPlural(n, one, few, many) {
621
+ const a = Math.abs(n) % 100;
622
+ const b = a % 10;
623
+ if (a > 10 && a < 20) {
624
+ return many;
625
+ }
626
+ return b === 1 ? one : b >= 2 && b <= 4 ? few : many;
627
+ }
628
+ /** Wording of {@link buildWeatherAnswer}. */
629
+ const ANSWER_TEXT = {
630
+ en: {
631
+ degrees: n => `${n} ${Math.abs(n) === 1 ? 'degree' : 'degrees'}`,
632
+ percent: n => `${n} percent`,
633
+ now: temp => `It is ${temp} outside`,
634
+ feels: temp => `feels like ${temp}`,
635
+ range: (min, max) => `${min} to ${max} degrees`,
636
+ chance: p => `${p} chance of rain`,
637
+ day: { today: 'Today', tomorrow: 'Tomorrow', dayAfter: 'The day after tomorrow' },
638
+ },
639
+ de: {
640
+ degrees: n => `${n} Grad`,
641
+ percent: n => `${n} Prozent`,
642
+ now: temp => `Draußen sind es ${temp}`,
643
+ feels: temp => `gefühlt ${temp}`,
644
+ range: (min, max) => `${min} bis ${max} Grad`,
645
+ chance: p => `Regenwahrscheinlichkeit ${p}`,
646
+ day: { today: 'Heute', tomorrow: 'Morgen', dayAfter: 'Übermorgen' },
647
+ },
648
+ ru: {
649
+ degrees: n => `${n} ${ruPlural(n, 'градус', 'градуса', 'градусов')}`,
650
+ percent: n => `${n} ${ruPlural(n, 'процент', 'процента', 'процентов')}`,
651
+ now: temp => `Сейчас на улице ${temp}`,
652
+ feels: temp => `ощущается как ${temp}`,
653
+ range: (min, max) => `от ${min} до ${max} ${ruPlural(max, 'градуса', 'градусов', 'градусов')}`,
654
+ chance: p => `вероятность осадков ${p}`,
655
+ day: { today: 'Сегодня', tomorrow: 'Завтра', dayAfter: 'Послезавтра' },
656
+ },
657
+ };
658
+ /** A condition text in the answer language: WMO texts are translated, adapter texts are kept as they come. */
659
+ function localCondition(condition, lang) {
660
+ const text = String(condition).trim();
661
+ return WMO_LOCAL[lang]?.[text.toLowerCase()] || text;
662
+ }
663
+ /**
664
+ * The spoken answer to a weather question, straight from the report — no LLM. `now` gives the current
665
+ * conditions plus today's range; `today`/`tomorrow`/`dayAfter` give that forecast day. Returns '' when the
666
+ * report has nothing for the asked day, so the caller can hand the question on.
667
+ */
668
+ function buildWeatherAnswer(report, lang, when = 'now') {
669
+ const t = ANSWER_TEXT[lang] || ANSWER_TEXT.en;
670
+ const r = Math.round;
671
+ const sentences = [];
672
+ const c = report.current;
673
+ if (when === 'now' && c && (c.temperature !== undefined || c.condition)) {
674
+ const parts = [];
675
+ if (c.temperature !== undefined) {
676
+ parts.push(t.now(t.degrees(r(c.temperature))));
677
+ // Only worth a word when it differs noticeably (wind chill, humid heat).
678
+ if (c.feelsLike !== undefined && Math.abs(c.feelsLike - c.temperature) >= 3) {
679
+ parts.push(t.feels(t.degrees(r(c.feelsLike))));
680
+ }
681
+ }
682
+ if (c.condition) {
683
+ parts.push(localCondition(c.condition, lang));
684
+ }
685
+ sentences.push(`${parts.join(', ')}.`);
686
+ }
687
+ const dayIndex = when === 'tomorrow' ? 1 : when === 'dayAfter' ? 2 : 0;
688
+ const d = report.forecast.find(f => f.day === dayIndex);
689
+ let dayParts = 0;
690
+ if (d) {
691
+ const parts = [];
692
+ if (d.tempMin !== undefined && d.tempMax !== undefined) {
693
+ parts.push(t.range(r(d.tempMin), r(d.tempMax)));
694
+ }
695
+ else if (d.tempMax !== undefined) {
696
+ parts.push(t.degrees(r(d.tempMax)));
697
+ }
698
+ if (d.condition) {
699
+ parts.push(localCondition(d.condition, lang));
700
+ }
701
+ if (d.precipProbability !== undefined) {
702
+ parts.push(t.chance(t.percent(r(d.precipProbability))));
703
+ }
704
+ if (parts.length) {
705
+ dayParts = parts.length;
706
+ sentences.push(`${t.day[when === 'now' ? 'today' : when]} ${parts.join(', ')}.`);
707
+ }
708
+ }
709
+ // A forecast day without data cannot be answered from the current conditions.
710
+ if (when !== 'now' && !dayParts) {
711
+ return '';
712
+ }
713
+ return sentences.join(' ');
714
+ }
555
715
  //# sourceMappingURL=weather.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"weather.js","sourceRoot":"","sources":["../../src/lib/weather.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Weather understanding — reads a user-selected ioBroker weather adapter's states and normalizes their\n * (wildly different) state trees into one compact {@link WeatherReport} the LLM can answer from.\n *\n * Each weather adapter names its states differently, so there is one small mapper per adapter \"kind\"\n * (verified against the adapters' source):\n * - `openmeteo` → `open-meteo-weather` (H5N1v2): `<root>.weather.current.*`, `<root>.weather.forecast.dayN.*`\n * - `wunderground` → `weatherunderground`: `<root>.forecast.current.*`, `<root>.forecast.Nd.*`\n * - `openweathermap` → `openweathermap`: `<root>.forecast.current.*`, `<root>.forecast.dayN.*`\n * Adapters without a mapper fall back to a raw state dump (handled by the caller), so the dropdown can still\n * offer them and the LLM can attempt an answer.\n */\n\n/** How to read a given weather adapter's state tree. */\nexport type WeatherKind =\n 'openmeteo' | 'wunderground' | 'openweathermap' | 'brightsky' | 'pirate' | 'accuweather' | 'daswetter' | 'yr';\n\n/**\n * Registry of weather adapters offered in the settings dropdown. `kind` present = fully normalized.\n * `perLocationProbe` (a state path that exists once per location) marks adapters that namespace their data\n * under a per-location device, so the dropdown lists each location separately (its first path segment is\n * used to split the location out of the state id).\n */\nexport const WEATHER_ADAPTERS: Record<string, { label: string; kind?: WeatherKind; perLocationProbe?: string }> = {\n 'open-meteo-weather': {\n label: 'Open-Meteo',\n kind: 'openmeteo',\n perLocationProbe: 'weather.current.temperature_2m',\n },\n weatherunderground: { label: 'Weather Underground', kind: 'wunderground' },\n openweathermap: { label: 'OpenWeatherMap', kind: 'openweathermap' },\n brightsky: { label: 'Bright Sky (DWD, free)', kind: 'brightsky' },\n 'pirate-weather': { label: 'Pirate Weather', kind: 'pirate' },\n accuweather: { label: 'AccuWeather', kind: 'accuweather' },\n daswetter: {\n label: 'DasWetter (Meteored)',\n kind: 'daswetter',\n perLocationProbe: 'ForecastDaily.Day_1.Temperature_Max',\n },\n yr: { label: 'Yr / met.no', kind: 'yr' },\n dwd: { label: 'DWD (warnings only)' },\n};\n\n/** Current conditions, normalized. All fields optional (an adapter may not provide them). */\nexport interface WeatherCurrent {\n temperature?: number;\n feelsLike?: number;\n humidity?: number;\n condition?: string;\n windSpeed?: number;\n windDir?: string | number;\n pressure?: number;\n precipitation?: number;\n cloudCover?: number;\n uvIndex?: number;\n}\n\n/** One forecast day, normalized. */\nexport interface WeatherDay {\n day: number;\n date?: string;\n tempMax?: number;\n tempMin?: number;\n condition?: string;\n precipProbability?: number;\n precipitation?: number;\n windSpeed?: number;\n windDir?: string | number;\n}\n\nexport interface WeatherReport {\n /** Adapter name the data came from. */\n source: string;\n /** Location name, if the root path carries one (Open-Meteo). */\n location?: string;\n /** Unit labels for the numeric values (the weather adapter's default units). */\n units: { temp: string; wind: string; precip: string };\n current?: WeatherCurrent;\n forecast: WeatherDay[];\n}\n\n/** A flat map of state id → value (as returned by getForeignStates, `.val` already unwrapped by the caller). */\nexport type StateValues = Record<string, unknown>;\n\n/** WMO weather-code → short English text, used when an adapter gives only a numeric code. */\nconst WMO_TEXT: Record<number, string> = {\n 0: 'clear sky',\n 1: 'mainly clear',\n 2: 'partly cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'depositing rime fog',\n 51: 'light drizzle',\n 53: 'drizzle',\n 55: 'dense drizzle',\n 56: 'freezing drizzle',\n 57: 'dense freezing drizzle',\n 61: 'slight rain',\n 63: 'rain',\n 65: 'heavy rain',\n 66: 'freezing rain',\n 67: 'heavy freezing rain',\n 71: 'slight snow',\n 73: 'snow',\n 75: 'heavy snow',\n 77: 'snow grains',\n 80: 'slight rain showers',\n 81: 'rain showers',\n 82: 'violent rain showers',\n 85: 'snow showers',\n 86: 'heavy snow showers',\n 95: 'thunderstorm',\n 96: 'thunderstorm with slight hail',\n 99: 'thunderstorm with heavy hail',\n};\n\n/** Human text for a WMO code (or '' if unknown). */\nexport function wmoText(code: unknown): string {\n const n = typeof code === 'number' ? code : parseInt(String(code), 10);\n return Number.isFinite(n) ? WMO_TEXT[n] || '' : '';\n}\n\nfunction num(states: StateValues, id: string): number | undefined {\n const v = states[id];\n if (v === undefined || v === null || v === '') {\n return undefined;\n }\n const n = typeof v === 'number' ? v : parseFloat(v == null ? '0' : (v as string).toString());\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction str(states: StateValues, id: string): string | undefined {\n const v = states[id];\n if (v == null || v === '') {\n return undefined;\n }\n return (v as string).toString();\n}\n\n/** First defined number among several candidate ids (for adapters with windowed/variant fields). */\nfunction firstNum(states: StateValues, ids: string[]): number | undefined {\n for (const id of ids) {\n const n = num(states, id);\n if (n !== undefined) {\n return n;\n }\n }\n return undefined;\n}\n\n/** First defined string among several candidate ids. */\nfunction firstStr(states: StateValues, ids: string[]): string | undefined {\n for (const id of ids) {\n const s = str(states, id);\n if (s !== undefined) {\n return s;\n }\n }\n return undefined;\n}\n\n/** Number of forecast days present under `dayId(i)` (probe until a day has no max-temp). */\nfunction countDays(states: StateValues, maxId: (i: number) => string, cap = 8): number {\n let n = 0;\n for (let i = 0; i < cap; i++) {\n if (num(states, maxId(i)) === undefined && str(states, maxId(i)) === undefined) {\n break;\n }\n n++;\n }\n return n;\n}\n\nfunction mapOpenMeteo(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature_2m`),\n feelsLike: num(states, `${c}.apparent_temperature`),\n humidity: num(states, `${c}.relative_humidity_2m`),\n condition: str(states, `${c}.weather_text`) || wmoText(states[`${c}.weather_code`]),\n windSpeed: num(states, `${c}.wind_speed_10m`),\n windDir: str(states, `${c}.wind_direction_text`) ?? num(states, `${c}.wind_direction_10m`),\n pressure: num(states, `${c}.pressure_msl`),\n precipitation: num(states, `${c}.precipitation`),\n cloudCover: num(states, `${c}.cloud_cover`),\n };\n const dayBase = (i: number): string => `${root}.weather.forecast.day${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperature_2m_max`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.name_day`) || str(states, `${d}.time`),\n tempMax: num(states, `${d}.temperature_2m_max`),\n tempMin: num(states, `${d}.temperature_2m_min`),\n condition: str(states, `${d}.weather_text`) || wmoText(states[`${d}.weather_code`]),\n precipProbability: num(states, `${d}.precipitation_probability_max`),\n precipitation: num(states, `${d}.precipitation_sum`),\n windSpeed: num(states, `${d}.wind_speed_10m_max`),\n windDir: num(states, `${d}.wind_direction_10m_dominant`),\n });\n }\n // Location = the segment between the instance (adapter.N) and the fixed \".weather\" suffix.\n const m = root.match(/^[^.]+\\.\\d+\\.(.+)$/);\n return {\n source: 'open-meteo-weather',\n location: m ? m[1].replace(/_/g, ' ') : undefined,\n units: { temp: '°C', wind: 'km/h', precip: 'mm' },\n current,\n forecast,\n };\n}\n\nfunction mapWunderground(root: string, states: StateValues): WeatherReport {\n const c = `${root}.forecast.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temp`),\n feelsLike: num(states, `${c}.feelsLike`),\n humidity: num(states, `${c}.relativeHumidity`),\n condition: str(states, `${c}.weather`),\n windSpeed: num(states, `${c}.wind`),\n windDir: str(states, `${c}.windDirection`) ?? num(states, `${c}.windDegrees`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipitationHour`),\n };\n const dayBase = (i: number): string => `${root}.forecast.${i}d`;\n const days = countDays(states, i => `${dayBase(i)}.tempMax`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.date`),\n tempMax: num(states, `${d}.tempMax`),\n tempMin: num(states, `${d}.tempMin`),\n condition: str(states, `${d}.state`),\n precipProbability: num(states, `${d}.precipitationChance`),\n precipitation: num(states, `${d}.precipitationAllDay`),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windDirection`),\n });\n }\n return { source: 'weatherunderground', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapOpenWeatherMap(root: string, states: StateValues): WeatherReport {\n const c = `${root}.forecast.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.feelsLike`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.state`) || str(states, `${c}.title`),\n windSpeed: num(states, `${c}.windSpeed`),\n windDir: str(states, `${c}.windDirectionText`) ?? num(states, `${c}.windDirection`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipitationRain`),\n };\n const dayBase = (i: number): string => `${root}.forecast.day${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperatureMax`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.date`),\n tempMax: num(states, `${d}.temperatureMax`),\n tempMin: num(states, `${d}.temperatureMin`),\n condition: str(states, `${d}.state`) || str(states, `${d}.title`),\n precipitation: num(states, `${d}.precipitationRain`),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windDirectionText`),\n });\n }\n // OpenWeatherMap reports wind in m/s.\n return { source: 'openweathermap', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast };\n}\n\nfunction mapBrightsky(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.apparent_temperature`),\n humidity: num(states, `${c}.relative_humidity`),\n condition: firstStr(states, [`${c}.conditionUI`, `${c}.condition`]),\n windSpeed: firstNum(states, [`${c}.wind_speed_60`, `${c}.wind_speed_10`, `${c}.wind_speed_30`]),\n windDir:\n firstStr(states, [`${c}.wind_bearing_text`]) ??\n firstNum(states, [`${c}.wind_direction_60`, `${c}.wind_direction_10`]),\n pressure: num(states, `${c}.pressure_msl`),\n precipitation: firstNum(states, [`${c}.precipitation_60`, `${c}.precipitation_10`]),\n cloudCover: num(states, `${c}.cloud_cover`),\n };\n const dayBase = (i: number): string => `${root}.weather.daily.${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperature_max`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: firstStr(states, [`${d}.dayName_long`, `${d}.dayName_short`]),\n tempMax: num(states, `${d}.temperature_max`),\n tempMin: num(states, `${d}.temperature_min`),\n condition: str(states, `${d}.condition`),\n precipProbability: num(states, `${d}.precipitation_probability_median`),\n precipitation: num(states, `${d}.precipitation`),\n windSpeed: firstNum(states, [`${d}.wind_speed_max`, `${d}.wind_speed_median`]),\n windDir: num(states, `${d}.wind_direction_median`),\n });\n }\n return { source: 'brightsky', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapPirate(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.currently`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.apparentTemperature`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.summary`),\n windSpeed: num(states, `${c}.windSpeed`),\n windDir: str(states, `${c}.windBearingText`) ?? num(states, `${c}.windBearing`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipIntensity`),\n cloudCover: num(states, `${c}.cloudCover`),\n };\n const dayBase = (i: number): string => `${root}.weather.daily.${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperatureHigh`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.time`),\n tempMax: num(states, `${d}.temperatureHigh`),\n tempMin: num(states, `${d}.temperatureLow`),\n condition: str(states, `${d}.summary`),\n precipProbability: num(states, `${d}.precipProbability`),\n precipitation: firstNum(states, [`${d}.precipAccumulation`, `${d}.precipIntensity`]),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windBearingText`) ?? num(states, `${d}.windBearing`),\n });\n }\n // Pirate Weather defaults to SI units (wind m/s).\n return { source: 'pirate-weather', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast };\n}\n\nfunction mapAccuweather(root: string, states: StateValues): WeatherReport {\n const c = `${root}.Current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.Temperature`),\n feelsLike: num(states, `${c}.RealFeelTemperature`),\n humidity: num(states, `${c}.RelativeHumidity`),\n condition: str(states, `${c}.WeatherText`),\n windSpeed: num(states, `${c}.WindSpeed`),\n windDir: str(states, `${c}.WindDirectionText`) ?? num(states, `${c}.WindDirection`),\n pressure: num(states, `${c}.Pressure`),\n cloudCover: num(states, `${c}.CloudCover`),\n uvIndex: num(states, `${c}.UVIndex`),\n };\n // AccuWeather days are the fixed folders Day1..Day5 (i logical → Day${i+1}).\n const dayBase = (i: number): string => `${root}.Daily.Day${i + 1}`;\n const days = countDays(states, i => `${dayBase(i)}.Temperature.Maximum`, 6);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.Date`),\n tempMax: num(states, `${d}.Temperature.Maximum`),\n tempMin: num(states, `${d}.Temperature.Minimum`),\n condition: firstStr(states, [`${d}.Day.IconPhrase`, `${d}.Day.ShortPhrase`]),\n precipProbability: num(states, `${d}.Day.PrecipitationProbability`),\n windSpeed: num(states, `${d}.Day.WindSpeed`),\n windDir: str(states, `${d}.Day.WindDirection`),\n });\n }\n // Metric config is the default (°C, km/h).\n return { source: 'accuweather', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapDasWetter(root: string, states: StateValues): WeatherReport {\n // Current is a copy of an hourly record (only present when CopyCurrentHour is enabled).\n const c = `${root}.ForecastHourly.Current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.temperature_feels_like`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.symbol_description`),\n windSpeed: num(states, `${c}.wind_speed`),\n windDir: str(states, `${c}.wind_direction`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.rain`),\n cloudCover: num(states, `${c}.clouds`),\n };\n // Daily folders are Day_1..Day_5 (i logical → Day_${i+1}).\n const dayBase = (i: number): string => `${root}.ForecastDaily.Day_${i + 1}`;\n const days = countDays(states, i => `${dayBase(i)}.Temperature_Max`, 6);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: firstStr(states, [`${d}.NameOfDay`, `${d}.date`]),\n tempMax: num(states, `${d}.Temperature_Max`),\n tempMin: num(states, `${d}.Temperature_Min`),\n condition: str(states, `${d}.symbol_description`),\n precipProbability: num(states, `${d}.Rain_Probability`),\n precipitation: num(states, `${d}.Rain`),\n windSpeed: num(states, `${d}.Wind_Speed`),\n windDir: str(states, `${d}.Wind_Direction`),\n });\n }\n return { source: 'daswetter', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapYr(root: string, states: StateValues): WeatherReport {\n // met.no is hourly-only; the nearest hour (`forecastHourly.0h`) is the closest thing to \"current\".\n const c = `${root}.forecastHourly.0h`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.air_temperature`),\n humidity: num(states, `${c}.relative_humidity`),\n condition: firstStr(states, [`${c}.1h_summary_text`, `${c}.6h_summary_text`]),\n windSpeed: num(states, `${c}.wind_speed`),\n windDir: num(states, `${c}.wind_from_direction`),\n pressure: num(states, `${c}.air_pressure_at_sea_level`),\n precipitation: num(states, `${c}.1h_precipitation_amount`),\n cloudCover: num(states, `${c}.cloud_area_fraction`),\n };\n // No daily/multi-day branch in the yr adapter → forecast stays empty.\n return { source: 'yr', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast: [] };\n}\n\n/**\n * Build a normalized {@link WeatherReport} from a weather adapter's flat state map. `adapter` is the adapter\n * name (segment 0 of the instance id); `root` is the state prefix the data lives under (for Open-Meteo this\n * includes the location device, e.g. `open-meteo-weather.0.Berlin`). Returns null for adapters without a\n * mapper (the caller then falls back to a raw dump) or when no data is present.\n */\nexport function buildWeatherReport(adapter: string, root: string, states: StateValues): WeatherReport | null {\n const kind = WEATHER_ADAPTERS[adapter]?.kind;\n if (!kind) {\n return null;\n }\n const mappers: Record<WeatherKind, (root: string, states: StateValues) => WeatherReport> = {\n openmeteo: mapOpenMeteo,\n wunderground: mapWunderground,\n openweathermap: mapOpenWeatherMap,\n brightsky: mapBrightsky,\n pirate: mapPirate,\n accuweather: mapAccuweather,\n daswetter: mapDasWetter,\n yr: mapYr,\n };\n const report = mappers[kind](root, states);\n // Drop empty/undefined fields from `current` so the report is compact (and a data-less selection\n // collapses to no current at all, rather than a stray empty condition string).\n if (report.current) {\n report.current = Object.fromEntries(\n Object.entries(report.current).filter(([, v]) => v !== undefined && v !== ''),\n );\n if (!Object.keys(report.current).length) {\n report.current = undefined;\n }\n }\n if (!report.current && !report.forecast.length) {\n return null; // adapter selected but no data yet\n }\n return report;\n}\n\n/** Keep only the forecast days a question needs: 'current'/'today' → day 0, 'tomorrow' → day 1, 'week' → all. */\nexport function trimReport(report: WeatherReport, when?: string): WeatherReport {\n const w = (when || '').toLowerCase();\n if (w === 'tomorrow') {\n return { ...report, forecast: report.forecast.filter(d => d.day === 1) };\n }\n if (w === 'today' || w === 'current' || w === 'now') {\n return { ...report, forecast: report.forecast.filter(d => d.day === 0) };\n }\n return report; // 'week' / unspecified → everything\n}\n\n/** Localized wording for {@link buildWeatherPrompt} (the assistant's voice languages: de/en/ru). */\nconst PROMPT_LABELS: Record<string, Record<string, string>> = {\n en: {\n header: 'Current weather',\n feels: 'feels like',\n wind: 'wind',\n humidity: 'humidity',\n precip: 'precipitation',\n clouds: 'cloud cover',\n uv: 'UV index',\n pressure: 'pressure',\n today: 'Today',\n tomorrow: 'Tomorrow',\n chance: 'precipitation probability',\n max: 'max',\n min: 'min',\n hint: 'Answer weather questions from this data; call get_weather only for days beyond tomorrow.',\n },\n de: {\n header: 'Aktuelles Wetter',\n feels: 'gefühlt',\n wind: 'Wind',\n humidity: 'Luftfeuchte',\n precip: 'Niederschlag',\n clouds: 'Bewölkung',\n uv: 'UV-Index',\n pressure: 'Luftdruck',\n today: 'Heute',\n tomorrow: 'Morgen',\n chance: 'Niederschlagswahrscheinlichkeit',\n max: 'max.',\n min: 'min.',\n hint: 'Beantworte Wetterfragen aus diesen Daten; rufe get_weather nur für Tage nach morgen auf.',\n },\n ru: {\n header: 'Текущая погода',\n feels: 'ощущается как',\n wind: 'ветер',\n humidity: 'влажность',\n precip: 'осадки',\n clouds: 'облачность',\n uv: 'УФ-индекс',\n pressure: 'давление',\n today: 'Сегодня',\n tomorrow: 'Завтра',\n chance: 'вероятность осадков',\n max: 'макс.',\n min: 'мин.',\n hint: 'Отвечай на вопросы о погоде по этим данным; вызывай get_weather только для дней после завтра.',\n },\n};\n\n/** At most one decimal — weather values carry no meaningful precision beyond that. */\nfunction fmtNum(v: number): string {\n return String(Math.round(v * 10) / 10);\n}\n\n/**\n * Compact, localized summary of the current conditions plus today/tomorrow, meant to be prepended to the\n * LLM's user turn so it can answer \"how's the weather?\" straight away — no `get_weather` round-trip, and\n * small/local models (which have no tools at all) can answer instead of inventing a forecast. Days beyond\n * tomorrow stay behind the tool so the injected block stays short. Returns '' if the report carries nothing.\n */\nexport function buildWeatherPrompt(report: WeatherReport, lang: string): string {\n const t = PROMPT_LABELS[lang] || PROMPT_LABELS.en;\n const u = report.units;\n const lines: string[] = [];\n const where = [WEATHER_ADAPTERS[report.source]?.label || report.source, report.location].filter(Boolean).join(', ');\n const c = report.current;\n if (c) {\n const parts: string[] = [];\n if (c.temperature !== undefined) {\n const feels = c.feelsLike !== undefined ? ` (${t.feels} ${fmtNum(c.feelsLike)} ${u.temp})` : '';\n parts.push(`${fmtNum(c.temperature)} ${u.temp}${feels}`);\n }\n if (c.condition) {\n parts.push(String(c.condition));\n }\n if (c.windSpeed !== undefined) {\n parts.push(`${t.wind} ${fmtNum(c.windSpeed)} ${u.wind}`);\n }\n if (c.humidity !== undefined) {\n parts.push(`${t.humidity} ${fmtNum(c.humidity)} %`);\n }\n if (c.precipitation !== undefined) {\n parts.push(`${t.precip} ${fmtNum(c.precipitation)} ${u.precip}`);\n }\n if (c.cloudCover !== undefined) {\n parts.push(`${t.clouds} ${fmtNum(c.cloudCover)} %`);\n }\n if (c.uvIndex !== undefined) {\n parts.push(`${t.uv} ${fmtNum(c.uvIndex)}`);\n }\n if (c.pressure !== undefined) {\n parts.push(`${t.pressure} ${fmtNum(c.pressure)} hPa`);\n }\n if (parts.length) {\n lines.push(`${t.header} (${where}): ${parts.join(', ')}.`);\n }\n }\n for (const d of report.forecast.filter(f => f.day === 0 || f.day === 1)) {\n const parts: string[] = [];\n if (d.tempMin !== undefined && d.tempMax !== undefined) {\n parts.push(`${fmtNum(d.tempMin)}…${fmtNum(d.tempMax)} ${u.temp}`);\n } else if (d.tempMax !== undefined) {\n parts.push(`${t.max} ${fmtNum(d.tempMax)} ${u.temp}`);\n } else if (d.tempMin !== undefined) {\n parts.push(`${t.min} ${fmtNum(d.tempMin)} ${u.temp}`);\n }\n if (d.condition) {\n parts.push(String(d.condition));\n }\n if (d.precipProbability !== undefined) {\n parts.push(`${t.chance} ${fmtNum(d.precipProbability)} %`);\n }\n if (d.precipitation !== undefined) {\n parts.push(`${t.precip} ${fmtNum(d.precipitation)} ${u.precip}`);\n }\n if (d.windSpeed !== undefined) {\n parts.push(`${t.wind} ${fmtNum(d.windSpeed)} ${u.wind}`);\n }\n if (parts.length) {\n lines.push(`${d.day === 0 ? t.today : t.tomorrow}: ${parts.join(', ')}.`);\n }\n }\n if (!lines.length) {\n return '';\n }\n lines.push(t.hint);\n return lines.join('\\n');\n}\n"]}
1
+ {"version":3,"file":"weather.js","sourceRoot":"","sources":["../../src/lib/weather.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Weather understanding — reads a user-selected ioBroker weather adapter's states and normalizes their\n * (wildly different) state trees into one compact {@link WeatherReport} the LLM can answer from.\n *\n * Each weather adapter names its states differently, so there is one small mapper per adapter \"kind\"\n * (verified against the adapters' source):\n * - `openmeteo` → `open-meteo-weather` (H5N1v2): `<root>.weather.current.*`, `<root>.weather.forecast.dayN.*`\n * - `wunderground` → `weatherunderground`: `<root>.forecast.current.*`, `<root>.forecast.Nd.*`\n * - `openweathermap` → `openweathermap`: `<root>.forecast.current.*`, `<root>.forecast.dayN.*`\n * Adapters without a mapper fall back to a raw state dump (handled by the caller), so the dropdown can still\n * offer them and the LLM can attempt an answer.\n */\n\n/** How to read a given weather adapter's state tree. */\nexport type WeatherKind =\n 'openmeteo' | 'wunderground' | 'openweathermap' | 'brightsky' | 'pirate' | 'accuweather' | 'daswetter' | 'yr';\n\n/**\n * Registry of weather adapters offered in the settings dropdown. `kind` present = fully normalized.\n * `perLocationProbe` (a state path that exists once per location) marks adapters that namespace their data\n * under a per-location device, so the dropdown lists each location separately (its first path segment is\n * used to split the location out of the state id).\n */\nexport const WEATHER_ADAPTERS: Record<string, { label: string; kind?: WeatherKind; perLocationProbe?: string }> = {\n 'open-meteo-weather': {\n label: 'Open-Meteo',\n kind: 'openmeteo',\n perLocationProbe: 'weather.current.temperature_2m',\n },\n weatherunderground: { label: 'Weather Underground', kind: 'wunderground' },\n openweathermap: { label: 'OpenWeatherMap', kind: 'openweathermap' },\n brightsky: { label: 'Bright Sky (DWD, free)', kind: 'brightsky' },\n 'pirate-weather': { label: 'Pirate Weather', kind: 'pirate' },\n accuweather: { label: 'AccuWeather', kind: 'accuweather' },\n daswetter: {\n label: 'DasWetter (Meteored)',\n kind: 'daswetter',\n perLocationProbe: 'ForecastDaily.Day_1.Temperature_Max',\n },\n yr: { label: 'Yr / met.no', kind: 'yr' },\n dwd: { label: 'DWD (warnings only)' },\n};\n\n/** Current conditions, normalized. All fields optional (an adapter may not provide them). */\nexport interface WeatherCurrent {\n temperature?: number;\n feelsLike?: number;\n humidity?: number;\n condition?: string;\n windSpeed?: number;\n windDir?: string | number;\n pressure?: number;\n precipitation?: number;\n cloudCover?: number;\n uvIndex?: number;\n}\n\n/** One forecast day, normalized. */\nexport interface WeatherDay {\n day: number;\n date?: string;\n tempMax?: number;\n tempMin?: number;\n condition?: string;\n precipProbability?: number;\n precipitation?: number;\n windSpeed?: number;\n windDir?: string | number;\n}\n\nexport interface WeatherReport {\n /** Adapter name the data came from. */\n source: string;\n /** Location name, if the root path carries one (Open-Meteo). */\n location?: string;\n /** Unit labels for the numeric values (the weather adapter's default units). */\n units: { temp: string; wind: string; precip: string };\n current?: WeatherCurrent;\n forecast: WeatherDay[];\n}\n\n/** A flat map of state id → value (as returned by getForeignStates, `.val` already unwrapped by the caller). */\nexport type StateValues = Record<string, unknown>;\n\n/** WMO weather-code → short English text, used when an adapter gives only a numeric code. */\nconst WMO_TEXT: Record<number, string> = {\n 0: 'clear sky',\n 1: 'mainly clear',\n 2: 'partly cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'depositing rime fog',\n 51: 'light drizzle',\n 53: 'drizzle',\n 55: 'dense drizzle',\n 56: 'freezing drizzle',\n 57: 'dense freezing drizzle',\n 61: 'slight rain',\n 63: 'rain',\n 65: 'heavy rain',\n 66: 'freezing rain',\n 67: 'heavy freezing rain',\n 71: 'slight snow',\n 73: 'snow',\n 75: 'heavy snow',\n 77: 'snow grains',\n 80: 'slight rain showers',\n 81: 'rain showers',\n 82: 'violent rain showers',\n 85: 'snow showers',\n 86: 'heavy snow showers',\n 95: 'thunderstorm',\n 96: 'thunderstorm with slight hail',\n 99: 'thunderstorm with heavy hail',\n};\n\n/** Human text for a WMO code (or '' if unknown). */\nexport function wmoText(code: unknown): string {\n const n = typeof code === 'number' ? code : parseInt(String(code), 10);\n return Number.isFinite(n) ? WMO_TEXT[n] || '' : '';\n}\n\nfunction num(states: StateValues, id: string): number | undefined {\n const v = states[id];\n if (v === undefined || v === null || v === '') {\n return undefined;\n }\n const n = typeof v === 'number' ? v : parseFloat(v == null ? '0' : (v as string).toString());\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction str(states: StateValues, id: string): string | undefined {\n const v = states[id];\n if (v == null || v === '') {\n return undefined;\n }\n return (v as string).toString();\n}\n\n/** First defined number among several candidate ids (for adapters with windowed/variant fields). */\nfunction firstNum(states: StateValues, ids: string[]): number | undefined {\n for (const id of ids) {\n const n = num(states, id);\n if (n !== undefined) {\n return n;\n }\n }\n return undefined;\n}\n\n/** First defined string among several candidate ids. */\nfunction firstStr(states: StateValues, ids: string[]): string | undefined {\n for (const id of ids) {\n const s = str(states, id);\n if (s !== undefined) {\n return s;\n }\n }\n return undefined;\n}\n\n/** Number of forecast days present under `dayId(i)` (probe until a day has no max-temp). */\nfunction countDays(states: StateValues, maxId: (i: number) => string, cap = 8): number {\n let n = 0;\n for (let i = 0; i < cap; i++) {\n if (num(states, maxId(i)) === undefined && str(states, maxId(i)) === undefined) {\n break;\n }\n n++;\n }\n return n;\n}\n\nfunction mapOpenMeteo(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature_2m`),\n feelsLike: num(states, `${c}.apparent_temperature`),\n humidity: num(states, `${c}.relative_humidity_2m`),\n condition: str(states, `${c}.weather_text`) || wmoText(states[`${c}.weather_code`]),\n windSpeed: num(states, `${c}.wind_speed_10m`),\n windDir: str(states, `${c}.wind_direction_text`) ?? num(states, `${c}.wind_direction_10m`),\n pressure: num(states, `${c}.pressure_msl`),\n precipitation: num(states, `${c}.precipitation`),\n cloudCover: num(states, `${c}.cloud_cover`),\n };\n const dayBase = (i: number): string => `${root}.weather.forecast.day${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperature_2m_max`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.name_day`) || str(states, `${d}.time`),\n tempMax: num(states, `${d}.temperature_2m_max`),\n tempMin: num(states, `${d}.temperature_2m_min`),\n condition: str(states, `${d}.weather_text`) || wmoText(states[`${d}.weather_code`]),\n precipProbability: num(states, `${d}.precipitation_probability_max`),\n precipitation: num(states, `${d}.precipitation_sum`),\n windSpeed: num(states, `${d}.wind_speed_10m_max`),\n windDir: num(states, `${d}.wind_direction_10m_dominant`),\n });\n }\n // Location = the segment between the instance (adapter.N) and the fixed \".weather\" suffix.\n const m = root.match(/^[^.]+\\.\\d+\\.(.+)$/);\n return {\n source: 'open-meteo-weather',\n location: m ? m[1].replace(/_/g, ' ') : undefined,\n units: { temp: '°C', wind: 'km/h', precip: 'mm' },\n current,\n forecast,\n };\n}\n\nfunction mapWunderground(root: string, states: StateValues): WeatherReport {\n const c = `${root}.forecast.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temp`),\n feelsLike: num(states, `${c}.feelsLike`),\n humidity: num(states, `${c}.relativeHumidity`),\n condition: str(states, `${c}.weather`),\n windSpeed: num(states, `${c}.wind`),\n windDir: str(states, `${c}.windDirection`) ?? num(states, `${c}.windDegrees`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipitationHour`),\n };\n const dayBase = (i: number): string => `${root}.forecast.${i}d`;\n const days = countDays(states, i => `${dayBase(i)}.tempMax`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.date`),\n tempMax: num(states, `${d}.tempMax`),\n tempMin: num(states, `${d}.tempMin`),\n condition: str(states, `${d}.state`),\n precipProbability: num(states, `${d}.precipitationChance`),\n precipitation: num(states, `${d}.precipitationAllDay`),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windDirection`),\n });\n }\n return { source: 'weatherunderground', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapOpenWeatherMap(root: string, states: StateValues): WeatherReport {\n const c = `${root}.forecast.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.feelsLike`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.state`) || str(states, `${c}.title`),\n windSpeed: num(states, `${c}.windSpeed`),\n windDir: str(states, `${c}.windDirectionText`) ?? num(states, `${c}.windDirection`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipitationRain`),\n };\n const dayBase = (i: number): string => `${root}.forecast.day${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperatureMax`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.date`),\n tempMax: num(states, `${d}.temperatureMax`),\n tempMin: num(states, `${d}.temperatureMin`),\n condition: str(states, `${d}.state`) || str(states, `${d}.title`),\n precipitation: num(states, `${d}.precipitationRain`),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windDirectionText`),\n });\n }\n // OpenWeatherMap reports wind in m/s.\n return { source: 'openweathermap', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast };\n}\n\nfunction mapBrightsky(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.apparent_temperature`),\n humidity: num(states, `${c}.relative_humidity`),\n condition: firstStr(states, [`${c}.conditionUI`, `${c}.condition`]),\n windSpeed: firstNum(states, [`${c}.wind_speed_60`, `${c}.wind_speed_10`, `${c}.wind_speed_30`]),\n windDir:\n firstStr(states, [`${c}.wind_bearing_text`]) ??\n firstNum(states, [`${c}.wind_direction_60`, `${c}.wind_direction_10`]),\n pressure: num(states, `${c}.pressure_msl`),\n precipitation: firstNum(states, [`${c}.precipitation_60`, `${c}.precipitation_10`]),\n cloudCover: num(states, `${c}.cloud_cover`),\n };\n const dayBase = (i: number): string => `${root}.weather.daily.${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperature_max`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: firstStr(states, [`${d}.dayName_long`, `${d}.dayName_short`]),\n tempMax: num(states, `${d}.temperature_max`),\n tempMin: num(states, `${d}.temperature_min`),\n condition: str(states, `${d}.condition`),\n precipProbability: num(states, `${d}.precipitation_probability_median`),\n precipitation: num(states, `${d}.precipitation`),\n windSpeed: firstNum(states, [`${d}.wind_speed_max`, `${d}.wind_speed_median`]),\n windDir: num(states, `${d}.wind_direction_median`),\n });\n }\n return { source: 'brightsky', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapPirate(root: string, states: StateValues): WeatherReport {\n const c = `${root}.weather.currently`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.apparentTemperature`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.summary`),\n windSpeed: num(states, `${c}.windSpeed`),\n windDir: str(states, `${c}.windBearingText`) ?? num(states, `${c}.windBearing`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.precipIntensity`),\n cloudCover: num(states, `${c}.cloudCover`),\n };\n const dayBase = (i: number): string => `${root}.weather.daily.${i}`;\n const days = countDays(states, i => `${dayBase(i)}.temperatureHigh`);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.time`),\n tempMax: num(states, `${d}.temperatureHigh`),\n tempMin: num(states, `${d}.temperatureLow`),\n condition: str(states, `${d}.summary`),\n precipProbability: num(states, `${d}.precipProbability`),\n precipitation: firstNum(states, [`${d}.precipAccumulation`, `${d}.precipIntensity`]),\n windSpeed: num(states, `${d}.windSpeed`),\n windDir: str(states, `${d}.windBearingText`) ?? num(states, `${d}.windBearing`),\n });\n }\n // Pirate Weather defaults to SI units (wind m/s).\n return { source: 'pirate-weather', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast };\n}\n\nfunction mapAccuweather(root: string, states: StateValues): WeatherReport {\n const c = `${root}.Current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.Temperature`),\n feelsLike: num(states, `${c}.RealFeelTemperature`),\n humidity: num(states, `${c}.RelativeHumidity`),\n condition: str(states, `${c}.WeatherText`),\n windSpeed: num(states, `${c}.WindSpeed`),\n windDir: str(states, `${c}.WindDirectionText`) ?? num(states, `${c}.WindDirection`),\n pressure: num(states, `${c}.Pressure`),\n cloudCover: num(states, `${c}.CloudCover`),\n uvIndex: num(states, `${c}.UVIndex`),\n };\n // AccuWeather days are the fixed folders Day1..Day5 (i logical → Day${i+1}).\n const dayBase = (i: number): string => `${root}.Daily.Day${i + 1}`;\n const days = countDays(states, i => `${dayBase(i)}.Temperature.Maximum`, 6);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: str(states, `${d}.Date`),\n tempMax: num(states, `${d}.Temperature.Maximum`),\n tempMin: num(states, `${d}.Temperature.Minimum`),\n condition: firstStr(states, [`${d}.Day.IconPhrase`, `${d}.Day.ShortPhrase`]),\n precipProbability: num(states, `${d}.Day.PrecipitationProbability`),\n windSpeed: num(states, `${d}.Day.WindSpeed`),\n windDir: str(states, `${d}.Day.WindDirection`),\n });\n }\n // Metric config is the default (°C, km/h).\n return { source: 'accuweather', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapDasWetter(root: string, states: StateValues): WeatherReport {\n // Current is a copy of an hourly record (only present when CopyCurrentHour is enabled).\n const c = `${root}.ForecastHourly.Current`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.temperature`),\n feelsLike: num(states, `${c}.temperature_feels_like`),\n humidity: num(states, `${c}.humidity`),\n condition: str(states, `${c}.symbol_description`),\n windSpeed: num(states, `${c}.wind_speed`),\n windDir: str(states, `${c}.wind_direction`),\n pressure: num(states, `${c}.pressure`),\n precipitation: num(states, `${c}.rain`),\n cloudCover: num(states, `${c}.clouds`),\n };\n // Daily folders are Day_1..Day_5 (i logical → Day_${i+1}).\n const dayBase = (i: number): string => `${root}.ForecastDaily.Day_${i + 1}`;\n const days = countDays(states, i => `${dayBase(i)}.Temperature_Max`, 6);\n const forecast: WeatherDay[] = [];\n for (let i = 0; i < days; i++) {\n const d = dayBase(i);\n forecast.push({\n day: i,\n date: firstStr(states, [`${d}.NameOfDay`, `${d}.date`]),\n tempMax: num(states, `${d}.Temperature_Max`),\n tempMin: num(states, `${d}.Temperature_Min`),\n condition: str(states, `${d}.symbol_description`),\n precipProbability: num(states, `${d}.Rain_Probability`),\n precipitation: num(states, `${d}.Rain`),\n windSpeed: num(states, `${d}.Wind_Speed`),\n windDir: str(states, `${d}.Wind_Direction`),\n });\n }\n return { source: 'daswetter', units: { temp: '°C', wind: 'km/h', precip: 'mm' }, current, forecast };\n}\n\nfunction mapYr(root: string, states: StateValues): WeatherReport {\n // met.no is hourly-only; the nearest hour (`forecastHourly.0h`) is the closest thing to \"current\".\n const c = `${root}.forecastHourly.0h`;\n const current: WeatherCurrent = {\n temperature: num(states, `${c}.air_temperature`),\n humidity: num(states, `${c}.relative_humidity`),\n condition: firstStr(states, [`${c}.1h_summary_text`, `${c}.6h_summary_text`]),\n windSpeed: num(states, `${c}.wind_speed`),\n windDir: num(states, `${c}.wind_from_direction`),\n pressure: num(states, `${c}.air_pressure_at_sea_level`),\n precipitation: num(states, `${c}.1h_precipitation_amount`),\n cloudCover: num(states, `${c}.cloud_area_fraction`),\n };\n // No daily/multi-day branch in the yr adapter → forecast stays empty.\n return { source: 'yr', units: { temp: '°C', wind: 'm/s', precip: 'mm' }, current, forecast: [] };\n}\n\n/**\n * Build a normalized {@link WeatherReport} from a weather adapter's flat state map. `adapter` is the adapter\n * name (segment 0 of the instance id); `root` is the state prefix the data lives under (for Open-Meteo this\n * includes the location device, e.g. `open-meteo-weather.0.Berlin`). Returns null for adapters without a\n * mapper (the caller then falls back to a raw dump) or when no data is present.\n */\nexport function buildWeatherReport(adapter: string, root: string, states: StateValues): WeatherReport | null {\n const kind = WEATHER_ADAPTERS[adapter]?.kind;\n if (!kind) {\n return null;\n }\n const mappers: Record<WeatherKind, (root: string, states: StateValues) => WeatherReport> = {\n openmeteo: mapOpenMeteo,\n wunderground: mapWunderground,\n openweathermap: mapOpenWeatherMap,\n brightsky: mapBrightsky,\n pirate: mapPirate,\n accuweather: mapAccuweather,\n daswetter: mapDasWetter,\n yr: mapYr,\n };\n const report = mappers[kind](root, states);\n // Drop empty/undefined fields from `current` so the report is compact (and a data-less selection\n // collapses to no current at all, rather than a stray empty condition string).\n if (report.current) {\n report.current = Object.fromEntries(\n Object.entries(report.current).filter(([, v]) => v !== undefined && v !== ''),\n );\n if (!Object.keys(report.current).length) {\n report.current = undefined;\n }\n }\n if (!report.current && !report.forecast.length) {\n return null; // adapter selected but no data yet\n }\n return report;\n}\n\n/** Keep only the forecast days a question needs: 'current'/'today' → day 0, 'tomorrow' → day 1, 'week' → all. */\nexport function trimReport(report: WeatherReport, when?: string): WeatherReport {\n const w = (when || '').toLowerCase();\n if (w === 'tomorrow') {\n return { ...report, forecast: report.forecast.filter(d => d.day === 1) };\n }\n if (w === 'today' || w === 'current' || w === 'now') {\n return { ...report, forecast: report.forecast.filter(d => d.day === 0) };\n }\n return report; // 'week' / unspecified → everything\n}\n\n/** Localized wording for {@link buildWeatherPrompt} (the assistant's voice languages: de/en/ru). */\nconst PROMPT_LABELS: Record<string, Record<string, string>> = {\n en: {\n header: 'Current weather',\n feels: 'feels like',\n wind: 'wind',\n humidity: 'humidity',\n precip: 'precipitation',\n clouds: 'cloud cover',\n uv: 'UV index',\n pressure: 'pressure',\n today: 'Today',\n tomorrow: 'Tomorrow',\n chance: 'precipitation probability',\n max: 'max',\n min: 'min',\n hint: 'Answer weather questions from this data; call get_weather only for days beyond tomorrow.',\n },\n de: {\n header: 'Aktuelles Wetter',\n feels: 'gefühlt',\n wind: 'Wind',\n humidity: 'Luftfeuchte',\n precip: 'Niederschlag',\n clouds: 'Bewölkung',\n uv: 'UV-Index',\n pressure: 'Luftdruck',\n today: 'Heute',\n tomorrow: 'Morgen',\n chance: 'Niederschlagswahrscheinlichkeit',\n max: 'max.',\n min: 'min.',\n hint: 'Beantworte Wetterfragen aus diesen Daten; rufe get_weather nur für Tage nach morgen auf.',\n },\n ru: {\n header: 'Текущая погода',\n feels: 'ощущается как',\n wind: 'ветер',\n humidity: 'влажность',\n precip: 'осадки',\n clouds: 'облачность',\n uv: 'УФ-индекс',\n pressure: 'давление',\n today: 'Сегодня',\n tomorrow: 'Завтра',\n chance: 'вероятность осадков',\n max: 'макс.',\n min: 'мин.',\n hint: 'Отвечай на вопросы о погоде по этим данным; вызывай get_weather только для дней после завтра.',\n },\n};\n\n/** At most one decimal — weather values carry no meaningful precision beyond that. */\nfunction fmtNum(v: number): string {\n return String(Math.round(v * 10) / 10);\n}\n\n/**\n * Compact, localized summary of the current conditions plus today/tomorrow, meant to be prepended to the\n * LLM's user turn so it can answer \"how's the weather?\" straight away — no `get_weather` round-trip, and\n * small/local models (which have no tools at all) can answer instead of inventing a forecast. Days beyond\n * tomorrow stay behind the tool so the injected block stays short. Returns '' if the report carries nothing.\n */\nexport function buildWeatherPrompt(report: WeatherReport, lang: string): string {\n const t = PROMPT_LABELS[lang] || PROMPT_LABELS.en;\n const u = report.units;\n const lines: string[] = [];\n const where = [WEATHER_ADAPTERS[report.source]?.label || report.source, report.location].filter(Boolean).join(', ');\n const c = report.current;\n if (c) {\n const parts: string[] = [];\n if (c.temperature !== undefined) {\n const feels = c.feelsLike !== undefined ? ` (${t.feels} ${fmtNum(c.feelsLike)} ${u.temp})` : '';\n parts.push(`${fmtNum(c.temperature)} ${u.temp}${feels}`);\n }\n if (c.condition) {\n parts.push(String(c.condition));\n }\n if (c.windSpeed !== undefined) {\n parts.push(`${t.wind} ${fmtNum(c.windSpeed)} ${u.wind}`);\n }\n if (c.humidity !== undefined) {\n parts.push(`${t.humidity} ${fmtNum(c.humidity)} %`);\n }\n if (c.precipitation !== undefined) {\n parts.push(`${t.precip} ${fmtNum(c.precipitation)} ${u.precip}`);\n }\n if (c.cloudCover !== undefined) {\n parts.push(`${t.clouds} ${fmtNum(c.cloudCover)} %`);\n }\n if (c.uvIndex !== undefined) {\n parts.push(`${t.uv} ${fmtNum(c.uvIndex)}`);\n }\n if (c.pressure !== undefined) {\n parts.push(`${t.pressure} ${fmtNum(c.pressure)} hPa`);\n }\n if (parts.length) {\n lines.push(`${t.header} (${where}): ${parts.join(', ')}.`);\n }\n }\n for (const d of report.forecast.filter(f => f.day === 0 || f.day === 1)) {\n const parts: string[] = [];\n if (d.tempMin !== undefined && d.tempMax !== undefined) {\n parts.push(`${fmtNum(d.tempMin)}…${fmtNum(d.tempMax)} ${u.temp}`);\n } else if (d.tempMax !== undefined) {\n parts.push(`${t.max} ${fmtNum(d.tempMax)} ${u.temp}`);\n } else if (d.tempMin !== undefined) {\n parts.push(`${t.min} ${fmtNum(d.tempMin)} ${u.temp}`);\n }\n if (d.condition) {\n parts.push(String(d.condition));\n }\n if (d.precipProbability !== undefined) {\n parts.push(`${t.chance} ${fmtNum(d.precipProbability)} %`);\n }\n if (d.precipitation !== undefined) {\n parts.push(`${t.precip} ${fmtNum(d.precipitation)} ${u.precip}`);\n }\n if (d.windSpeed !== undefined) {\n parts.push(`${t.wind} ${fmtNum(d.windSpeed)} ${u.wind}`);\n }\n if (parts.length) {\n lines.push(`${d.day === 0 ? t.today : t.tomorrow}: ${parts.join(', ')}.`);\n }\n }\n if (!lines.length) {\n return '';\n }\n lines.push(t.hint);\n return lines.join('\\n');\n}\n\n/** WMO texts in the other voice languages, by the English text {@link wmoText} puts into a report. */\nconst WMO_LOCAL: Record<string, Record<string, string>> = {\n de: {\n 'clear sky': 'klarer Himmel',\n 'mainly clear': 'überwiegend klar',\n 'partly cloudy': 'teilweise bewölkt',\n overcast: 'bedeckt',\n fog: 'Nebel',\n 'depositing rime fog': 'Nebel mit Raureif',\n 'light drizzle': 'leichter Nieselregen',\n drizzle: 'Nieselregen',\n 'dense drizzle': 'starker Nieselregen',\n 'freezing drizzle': 'gefrierender Nieselregen',\n 'dense freezing drizzle': 'starker gefrierender Nieselregen',\n 'slight rain': 'leichter Regen',\n rain: 'Regen',\n 'heavy rain': 'starker Regen',\n 'freezing rain': 'gefrierender Regen',\n 'heavy freezing rain': 'starker gefrierender Regen',\n 'slight snow': 'leichter Schneefall',\n snow: 'Schneefall',\n 'heavy snow': 'starker Schneefall',\n 'snow grains': 'Schneegriesel',\n 'slight rain showers': 'leichte Regenschauer',\n 'rain showers': 'Regenschauer',\n 'violent rain showers': 'heftige Regenschauer',\n 'snow showers': 'Schneeschauer',\n 'heavy snow showers': 'starke Schneeschauer',\n thunderstorm: 'Gewitter',\n 'thunderstorm with slight hail': 'Gewitter mit leichtem Hagel',\n 'thunderstorm with heavy hail': 'Gewitter mit starkem Hagel',\n },\n ru: {\n 'clear sky': 'ясно',\n 'mainly clear': 'преимущественно ясно',\n 'partly cloudy': 'переменная облачность',\n overcast: 'пасмурно',\n fog: 'туман',\n 'depositing rime fog': 'туман с изморозью',\n 'light drizzle': 'лёгкая морось',\n drizzle: 'морось',\n 'dense drizzle': 'сильная морось',\n 'freezing drizzle': 'ледяная морось',\n 'dense freezing drizzle': 'сильная ледяная морось',\n 'slight rain': 'небольшой дождь',\n rain: 'дождь',\n 'heavy rain': 'сильный дождь',\n 'freezing rain': 'ледяной дождь',\n 'heavy freezing rain': 'сильный ледяной дождь',\n 'slight snow': 'небольшой снег',\n snow: 'снег',\n 'heavy snow': 'сильный снег',\n 'snow grains': 'снежная крупа',\n 'slight rain showers': 'небольшой ливень',\n 'rain showers': 'ливень',\n 'violent rain showers': 'сильный ливень',\n 'snow showers': 'снегопад',\n 'heavy snow showers': 'сильный снегопад',\n thunderstorm: 'гроза',\n 'thunderstorm with slight hail': 'гроза с небольшим градом',\n 'thunderstorm with heavy hail': 'гроза с сильным градом',\n },\n};\n\n/** Russian noun form after a number: 1 градус, 2 градуса, 5 градусов. */\nfunction ruPlural(n: number, one: string, few: string, many: string): string {\n const a = Math.abs(n) % 100;\n const b = a % 10;\n if (a > 10 && a < 20) {\n return many;\n }\n return b === 1 ? one : b >= 2 && b <= 4 ? few : many;\n}\n\n/** Wording of {@link buildWeatherAnswer}. */\nconst ANSWER_TEXT: Record<\n string,\n {\n degrees: (n: number) => string;\n percent: (n: number) => string;\n now: (temp: string) => string;\n feels: (temp: string) => string;\n range: (min: number, max: number) => string;\n chance: (p: string) => string;\n day: Record<'today' | 'tomorrow' | 'dayAfter', string>;\n }\n> = {\n en: {\n degrees: n => `${n} ${Math.abs(n) === 1 ? 'degree' : 'degrees'}`,\n percent: n => `${n} percent`,\n now: temp => `It is ${temp} outside`,\n feels: temp => `feels like ${temp}`,\n range: (min, max) => `${min} to ${max} degrees`,\n chance: p => `${p} chance of rain`,\n day: { today: 'Today', tomorrow: 'Tomorrow', dayAfter: 'The day after tomorrow' },\n },\n de: {\n degrees: n => `${n} Grad`,\n percent: n => `${n} Prozent`,\n now: temp => `Draußen sind es ${temp}`,\n feels: temp => `gefühlt ${temp}`,\n range: (min, max) => `${min} bis ${max} Grad`,\n chance: p => `Regenwahrscheinlichkeit ${p}`,\n day: { today: 'Heute', tomorrow: 'Morgen', dayAfter: 'Übermorgen' },\n },\n ru: {\n degrees: n => `${n} ${ruPlural(n, 'градус', 'градуса', 'градусов')}`,\n percent: n => `${n} ${ruPlural(n, 'процент', 'процента', 'процентов')}`,\n now: temp => `Сейчас на улице ${temp}`,\n feels: temp => `ощущается как ${temp}`,\n range: (min, max) => `от ${min} до ${max} ${ruPlural(max, 'градуса', 'градусов', 'градусов')}`,\n chance: p => `вероятность осадков ${p}`,\n day: { today: 'Сегодня', tomorrow: 'Завтра', dayAfter: 'Послезавтра' },\n },\n};\n\n/** A condition text in the answer language: WMO texts are translated, adapter texts are kept as they come. */\nfunction localCondition(condition: string, lang: string): string {\n const text = String(condition).trim();\n return WMO_LOCAL[lang]?.[text.toLowerCase()] || text;\n}\n\n/**\n * The spoken answer to a weather question, straight from the report — no LLM. `now` gives the current\n * conditions plus today's range; `today`/`tomorrow`/`dayAfter` give that forecast day. Returns '' when the\n * report has nothing for the asked day, so the caller can hand the question on.\n */\nexport function buildWeatherAnswer(\n report: WeatherReport,\n lang: string,\n when: 'now' | 'today' | 'tomorrow' | 'dayAfter' = 'now',\n): string {\n const t = ANSWER_TEXT[lang] || ANSWER_TEXT.en;\n const r = Math.round;\n const sentences: string[] = [];\n const c = report.current;\n if (when === 'now' && c && (c.temperature !== undefined || c.condition)) {\n const parts: string[] = [];\n if (c.temperature !== undefined) {\n parts.push(t.now(t.degrees(r(c.temperature))));\n // Only worth a word when it differs noticeably (wind chill, humid heat).\n if (c.feelsLike !== undefined && Math.abs(c.feelsLike - c.temperature) >= 3) {\n parts.push(t.feels(t.degrees(r(c.feelsLike))));\n }\n }\n if (c.condition) {\n parts.push(localCondition(c.condition, lang));\n }\n sentences.push(`${parts.join(', ')}.`);\n }\n const dayIndex = when === 'tomorrow' ? 1 : when === 'dayAfter' ? 2 : 0;\n const d = report.forecast.find(f => f.day === dayIndex);\n let dayParts = 0;\n if (d) {\n const parts: string[] = [];\n if (d.tempMin !== undefined && d.tempMax !== undefined) {\n parts.push(t.range(r(d.tempMin), r(d.tempMax)));\n } else if (d.tempMax !== undefined) {\n parts.push(t.degrees(r(d.tempMax)));\n }\n if (d.condition) {\n parts.push(localCondition(d.condition, lang));\n }\n if (d.precipProbability !== undefined) {\n parts.push(t.chance(t.percent(r(d.precipProbability))));\n }\n if (parts.length) {\n dayParts = parts.length;\n sentences.push(`${t.day[when === 'now' ? 'today' : when]} ${parts.join(', ')}.`);\n }\n }\n // A forecast day without data cannot be answered from the current conditions.\n if (when !== 'now' && !dayParts) {\n return '';\n }\n return sentences.join(' ');\n}\n"]}