From a473f6e0399aa82a2fefee572353fed0bedcf2fa Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Fri, 3 Apr 2026 00:52:54 -0400 Subject: [PATCH] fix: minichat markdown rendering and weather temperature unit preference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - KnowledgeView minichat: render assistant messages through renderMarkdown so headers, bold, lists etc. display correctly instead of raw markdown - get_weather tool: read user's temp_unit from briefing_config and convert temperatures to °F when preferred; also include temp_unit in the returned payload so the model can label values correctly Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/views/KnowledgeView.vue | 3 ++- src/fabledassistant/services/tools.py | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/frontend/src/views/KnowledgeView.vue b/frontend/src/views/KnowledgeView.vue index d3cc220..88245af 100644 --- a/frontend/src/views/KnowledgeView.vue +++ b/frontend/src/views/KnowledgeView.vue @@ -3,6 +3,7 @@ import { ref, computed, watch, onMounted, onUnmounted, nextTick } from "vue"; import { useRouter } from "vue-router"; import { apiGet, apiPatch, transcribeAudio } from "@/api/client"; import { fmtCompact } from "@/utils/dateFormat"; +import { renderMarkdown } from "@/utils/markdown"; import { useChatStore } from "@/stores/chat"; import { useSettingsStore } from "@/stores/settings"; import { useVoiceRecorder } from "@/composables/useVoiceRecorder"; @@ -544,7 +545,7 @@ onUnmounted(() => { class="minichat-msg" :class="msg.role === 'user' ? 'msg--user' : 'msg--assistant'" > -
+
diff --git a/src/fabledassistant/services/tools.py b/src/fabledassistant/services/tools.py index aa5a78b..47fe7b8 100644 --- a/src/fabledassistant/services/tools.py +++ b/src/fabledassistant/services/tools.py @@ -1914,20 +1914,34 @@ async def execute_tool( from fabledassistant.services.weather import ( get_cached_weather, geocode, _fetch_open_meteo, parse_forecast ) + from fabledassistant.services.briefing_pipeline import _get_temp_unit from datetime import timezone as _tz location = (arguments.get("location") or "").strip() + temp_unit = await _get_temp_unit(user_id) + + def _apply_unit(days: list[dict]) -> list[dict]: + if temp_unit != "F": + return days + def _c_to_f(v: float | None) -> float | None: + return round(v * 9 / 5 + 32, 1) if v is not None else None + return [ + {**d, "temp_max": _c_to_f(d.get("temp_max")), "temp_min": _c_to_f(d.get("temp_min"))} + for d in days + ] + _known = {"home", "work", "all", ""} if location.lower() not in _known: # Live geocode + fetch for arbitrary city try: lat, lon, label = await geocode(location) raw = await _fetch_open_meteo(lat, lon) - days = parse_forecast(raw) + days = _apply_unit(parse_forecast(raw)) return {"success": True, "data": {"locations": [{ "location_key": "query", "location_label": label, "fetched_at": datetime.now(_tz.utc).isoformat(), "days": days, + "temp_unit": temp_unit, "changes_since_last_fetch": [], }]}} except Exception as e: @@ -1936,6 +1950,10 @@ async def execute_tool( locations = await get_cached_weather(user_id) if location.lower() not in ("all", ""): locations = [loc for loc in locations if loc["location_key"] == location.lower()] + locations = [ + {**loc, "days": _apply_unit(loc.get("days", [])), "temp_unit": temp_unit} + for loc in locations + ] return {"success": True, "data": {"locations": locations}} elif tool_name == "get_rss_items":