From c4494b49ff54efb3bc1fa8e2b3bb48fae693b8e4 Mon Sep 17 00:00:00 2001 From: holden093 Date: Mon, 29 Jun 2026 14:24:41 +0200 Subject: [PATCH] fix(chat): use DEFAULT_MAX_TOKENS consistently across all call sites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace hardcoded 0 and 4096 in skills_routes.py with the canonical constant, and bump LLMConfig.DEFAULT_MAX_TOKENS from 0 to 4096 so function defaults match. The rewrite path (chat_routes.py:1572) keeps its intentional 0 — local reasoning models share their token budget with blocks and need to be uncapped there. Root cause: max_tokens=0 caused the OpenAI-compat payload builder to omit the param entirely, so upstreams like DeepSeek defaulted to a very short completion. --- routes/skills_routes.py | 9 +++------ src/llm_core.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/routes/skills_routes.py b/routes/skills_routes.py index 711baa2e5..146f2c053 100644 --- a/routes/skills_routes.py +++ b/routes/skills_routes.py @@ -18,6 +18,7 @@ from pydantic import BaseModel, Field from services.memory.skills import SkillsManager from src.auth_helpers import get_current_user +from src.constants import DEFAULT_MAX_TOKENS from core.middleware import require_admin logger = logging.getLogger(__name__) @@ -440,7 +441,7 @@ async def _run_skill_test_job(key, name, md, task, url, model, headers, owner, s try: async for chunk in stream_agent_loop( url, model, messages, headers=headers, - temperature=0.3, max_tokens=0, max_rounds=8, owner=owner, + temperature=0.3, max_tokens=DEFAULT_MAX_TOKENS, max_rounds=8, owner=owner, ): if not chunk.startswith("data: ") or chunk.strip() == "data: [DONE]": continue @@ -701,12 +702,8 @@ async def _run_skill_test_once(md: str, task: str, url, model, headers, owner) - {"role": "user", "content": task}, ] try: - # max_tokens explicitly set: passing 0 lets some upstreams (Ollama, - # OpenAI-compat) generate an empty completion, which manifested as - # the skill test returning nothing while chat (which carries its - # preset's max_tokens) worked. 4096 matches the chat default. async for chunk in stream_agent_loop(url, model, messages, headers=headers, - temperature=0.3, max_tokens=4096, max_rounds=8, owner=owner): + temperature=0.3, max_tokens=DEFAULT_MAX_TOKENS, max_rounds=8, owner=owner): if not chunk.startswith("data: ") or chunk.strip() == "data: [DONE]": continue try: diff --git a/src/llm_core.py b/src/llm_core.py index 4dec32376..f9e0525f5 100644 --- a/src/llm_core.py +++ b/src/llm_core.py @@ -94,7 +94,7 @@ class LLMConfig: """Configuration constants for LLM operations.""" DEFAULT_TIMEOUT = 30 DEFAULT_TEMPERATURE = 1.0 - DEFAULT_MAX_TOKENS = 0 + DEFAULT_MAX_TOKENS = 4096 MAX_RETRIES = 3 RETRY_DELAY = 0.5 STREAM_TIMEOUT = 300