From 6902c5887d31019a982bd263166556ca4450feea Mon Sep 17 00:00:00 2001 From: ingpedrofernandez Date: Sat, 4 Apr 2026 17:50:10 +0200 Subject: [PATCH 1/2] Fix reasoning_effort param and add watchlist scroll-to-new - Remove unsupported reasoning_effort="low" from LiteLLM call; this parameter is only valid for OpenAI reasoning models and causes errors with gpt-oss-120b via OpenRouter - Watchlist auto-scrolls to bottom after adding a ticker so the newly added item is immediately visible without manual scrolling Co-Authored-By: Claude Sonnet 4.6 --- backend/app/llm/service.py | 1 - frontend/components/Watchlist.tsx | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/app/llm/service.py b/backend/app/llm/service.py index adb86b15..1506012a 100644 --- a/backend/app/llm/service.py +++ b/backend/app/llm/service.py @@ -240,7 +240,6 @@ async def chat_with_llm(user_message: str, price_cache: PriceCache) -> dict: model=MODEL, messages=messages, response_format=LlmResponse, - reasoning_effort="low", extra_body=EXTRA_BODY, ) content = response.choices[0].message.content diff --git a/frontend/components/Watchlist.tsx b/frontend/components/Watchlist.tsx index 8db49ce2..2105eeb6 100644 --- a/frontend/components/Watchlist.tsx +++ b/frontend/components/Watchlist.tsx @@ -26,6 +26,7 @@ export default function Watchlist({ const [addInput, setAddInput] = useState(""); const prevPricesRef = useRef>({}); const rowRefs = useRef>({}); + const listRef = useRef(null); // Apply flash CSS classes directly to DOM elements useEffect(() => { @@ -51,6 +52,10 @@ export default function Watchlist({ await addToWatchlist(ticker); setAddInput(""); onRefresh(); + // Scroll to bottom to reveal the newly added ticker + setTimeout(() => { + if (listRef.current) listRef.current.scrollTop = listRef.current.scrollHeight; + }, 100); }, [addInput, onRefresh]); const handleRemove = useCallback( @@ -86,7 +91,7 @@ export default function Watchlist({ -
+
From 41388049e889ce1e3188a0d231869ccf6b73344f Mon Sep 17 00:00:00 2001 From: ingpedrofernandez Date: Sun, 5 Apr 2026 19:18:58 +0200 Subject: [PATCH 2/2] Fix LLM model config, watchlist ticker recovery, and chart resize - Switch LLM model to claude-sonnet-4-6 and remove extra_body param - Auto-recover watchlist tickers not tracked in price cache (e.g. from previous session) - Fix PriceChart resize handling with autoSize and absolute positioning Co-Authored-By: Claude Sonnet 4.6 --- backend/app/llm/service.py | 4 +--- backend/app/routes/watchlist.py | 5 +++++ frontend/components/PriceChart.tsx | 29 ++++++++++------------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/backend/app/llm/service.py b/backend/app/llm/service.py index 1506012a..b0156c81 100644 --- a/backend/app/llm/service.py +++ b/backend/app/llm/service.py @@ -26,8 +26,7 @@ logger = logging.getLogger(__name__) -MODEL = "openrouter/openai/gpt-oss-120b" -EXTRA_BODY = {"provider": {"order": ["cerebras"]}} +MODEL = "claude-sonnet-4-6" SYSTEM_PROMPT = """You are FinAlly, an AI trading assistant for a simulated trading workstation. @@ -240,7 +239,6 @@ async def chat_with_llm(user_message: str, price_cache: PriceCache) -> dict: model=MODEL, messages=messages, response_format=LlmResponse, - extra_body=EXTRA_BODY, ) content = response.choices[0].message.content llm_response = LlmResponse.model_validate_json(content) diff --git a/backend/app/routes/watchlist.py b/backend/app/routes/watchlist.py index 19133357..c0cdd60f 100644 --- a/backend/app/routes/watchlist.py +++ b/backend/app/routes/watchlist.py @@ -16,12 +16,17 @@ class AddTickerRequest(BaseModel): async def list_watchlist(request: Request): """Current watchlist tickers with latest prices from PriceCache.""" cache = request.app.state.price_cache + source = request.app.state.market_source watchlist = await get_watchlist() items = [] for entry in watchlist: ticker = entry["ticker"] update = cache.get(ticker) + # Auto-recover tickers not currently tracked (e.g., added in a previous session) + if update is None: + await source.add_ticker(ticker) + update = cache.get(ticker) items.append({ "ticker": ticker, "price": update.price if update else None, diff --git a/frontend/components/PriceChart.tsx b/frontend/components/PriceChart.tsx index 739b255e..bf9d345f 100644 --- a/frontend/components/PriceChart.tsx +++ b/frontend/components/PriceChart.tsx @@ -18,6 +18,7 @@ export default function PriceChart({ ticker, getHistory }: PriceChartProps) { if (!containerRef.current) return; const chart = createChart(containerRef.current, { + autoSize: true, layout: { background: { color: "#161b22" }, textColor: "#8b949e", @@ -52,16 +53,7 @@ export default function PriceChart({ ticker, getHistory }: PriceChartProps) { chartRef.current = chart; seriesRef.current = series; - const ro = new ResizeObserver((entries) => { - for (const entry of entries) { - const { width, height } = entry.contentRect; - chart.applyOptions({ width, height }); - } - }); - ro.observe(containerRef.current); - return () => { - ro.disconnect(); chart.remove(); chartRef.current = null; seriesRef.current = null; @@ -101,22 +93,21 @@ export default function PriceChart({ ticker, getHistory }: PriceChartProps) { }); }); - if (!ticker) { - return ( -
- Select a ticker from the watchlist -
- ); - } - return (

- {ticker} -- Price Chart + {ticker ? `${ticker} -- Price Chart` : "Price Chart"}

-
+
+
+ {!ticker && ( +
+ Select a ticker from the watchlist +
+ )} +
); }