The OpenAI Chat Completions API defaults `stream` to false, but ChatRequest.stream
was defaulting to True. As a result, any standard OpenAI-compatible client that
omits the `stream` field receives a `text/event-stream` response where it expects
plain JSON, and fails with:
AttributeError: 'str' object has no attribute 'choices'
Reproduce (openai==1.59.6):
from openai import OpenAI
c = OpenAI(base_url='http://localhost:8998/v1', api_key='none')
c.chat.completions.create(model='minimind', messages=[{'role':'user','content':'hi'}])
curl with an explicit "stream": false returns correct JSON, confirming the handler
logic is fine and only the default value is at fault.
Explicit `stream=True` requests are unaffected.
execute_tool() relied on signal.SIGALRM, which does not exist on Windows.
The AttributeError was swallowed by a bare except, so every tool call
silently returned None and the model always observed
{"error": "tool not found"} (issue #846).
calculate_math also ran eval() on model-generated text. Two of the three
call sites (scripts/eval_toolcall.py, scripts/web_demo.py) passed no
globals at all, leaving full builtins reachable from sampled output.
safe_math_eval() in trainer_utils.py parses the expression with ast and
walks it, allowing only arithmetic operators and a math whitelist, with
caps on expression length and exponent size. It cannot loop forever, so
the signal-based timeout is no longer needed and is removed. Both sqrt(x)
and math.sqrt(x) spellings keep working.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>