From 1729e1c399a41b4128b5dd7ef0286fae128e6157 Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Thu, 9 Jul 2026 21:52:16 +0900 Subject: ollama側のレスポンスが空の場合に1回リトライする処理に変更 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit トークン数の累積計算処理削除 --- src/ollama_web/llm.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/ollama_web/llm.py') diff --git a/src/ollama_web/llm.py b/src/ollama_web/llm.py index 48c177a..76a61a5 100644 --- a/src/ollama_web/llm.py +++ b/src/ollama_web/llm.py @@ -393,6 +393,9 @@ def stream_chat_with_tools( cumulative_tool_chars = 0 + MAX_EMPTY_RETRIES = 2 + empty_retries = 0 + rounds = 0 while rounds < MAX_TOOL_ROUNDS: rounds += 1 @@ -406,6 +409,7 @@ def stream_chat_with_tools( model, cumulative_tool_chars, ) + t0 = time.time() try: stream = cast(Any, raw_client).chat( @@ -449,6 +453,35 @@ def stream_chat_with_tools( time.time() - t0, ) + # Detect empty responses. Some models / proxies occasionally return a + # stream with almost no meaningful content. Log it and retry a few + # times before giving up. + is_empty = ( + not full_message.get("content") + and not full_message.get("thinking") + and not tool_calls + ) + if is_empty and empty_retries < MAX_EMPTY_RETRIES: + empty_retries += 1 + logger.warning( + "ollama returned an empty stream (chunks=%d); retry %d/%d", + chunk_count, + empty_retries, + MAX_EMPTY_RETRIES, + ) + yield { + "type": "status", + "message": t("status.empty_response_retry", lang=language), + } + # Retry the same round without consuming the tool round budget. + rounds -= 1 + # Small pause to avoid hammering the upstream. + time.sleep(0.5) + continue + # Reset retry budget on any non-empty round so isolated hiccups are fine. + if not is_empty: + empty_retries = 0 + # Reconstruct the assistant message including any tool_calls so the # next round can see them. if tool_calls: @@ -458,6 +491,12 @@ def stream_chat_with_tools( messages.append(msg) if not tool_calls: + if is_empty: + # Ran out of tool rounds while still empty; surface a warning. + yield { + "type": "warning", + "message": t("status.empty_response", lang=language), + } done_event = {"type": "done"} tokens = _token_counts(last_chunk) if tokens: -- cgit v1.2.3