Hi everyone! I'm running self-hosted OpenHands wit...
# general
s
Hi everyone! I'm running self-hosted OpenHands with GLM-5.3 via vLLM on 2× NVIDIA DGX Sparks. During longer tasks, OpenHands repeatedly executes the same commands before eventually showing "Agent error". The model and tools work initially, but this keeps happening. I found this potentially related issue: github.com/OpenHands/software-agent-sdk/issues/3112 Is this a known OpenHands/SDK issue, or could it be related to GLM tool calling or context management? Any recommended fixes?
m
I do think we had a similar issue once. (@calm-artist-7206 can confirm) And if I remember good it was a problem with the endpoint. Let me give a look
s
i appreciate your answer.
m
I sent an agent to search for what we did and here is the answer 🙂 --- So what to tell him (self-hosted GLM-5.3 via vLLM on 2× DGX Spark) 1. This is very likely a serving-side issue, not OpenHands — the fp4→fp8 provider switch is what fixed the same symptom for us. Check the quantization of the vLLM weights first. 2. Make sure the vLLM tool-call parser matches the model and
--enable-auto-tool-choice
is on — a mismatched/streaming parser produces exactly these repeated malformed calls. 3. Set temperature=1.0 for GLM (that's what Z.ai used in their own evals). 4. Verify the base URL ends in
/v1
(bit us before). 5. On the SDK side, #4332 is merged, so he should upgrade — he'll get the corrective nudge instead of an instant "Agent error", and stuck detection / max iterations are adjustable. There are still open PRs (#5707, #5783) fixing `maxIterations`/`stuckDetection` not being forwarded in some paths, so it's worth pinning a recent version. If he can share a trajectory, the fastest signal is the same one that cracked our case: look at the exact repeated tool call — whether it's a malformed call (parser/quantization) or a valid but redundant one (then it's genuinely stuck detection / prompt territory). --- Perhaps from my side: • can you share the version you are using? • a trajectory? Thanks
s
Thanks, Vasco! That would be very helpful. My setup uses OpenHands SDK v1.54.0 with GLM-5.3 Flash through a local vLLM OpenAI-compatible endpoint (
/v1/chat/completions
). I've confirmed that basic native tool calling works correctly, including processing tool results and stopping afterward. However, during longer conversations, OpenHands repeatedly executes identical commands with identical successful outputs until the stuck detector terminates the conversation. Do you remember whether the previous endpoint issue was related to streaming, tool-call formatting, context handling, or vLLM configuration? I'd appreciate any details about the fix you used.
Thanks Vasco, this is extremely helpful! Here are my environment details: • OpenHands Agent Canvas: 1.27.1 • OpenHands SDK: 1.54.0 • Model: GLM-5.3 Flash • Inference: local vLLM, tensor parallelism across 2 NVIDIA DGX Sparks • Model deployment: custom NVFP4/DFlash2 • API:
<http://192.168.41.28:8000/v1/chat/completions>
• OpenHands model identifier:
openai/glm-5.3-flash
• Temperature: 0.2 • Native tool calling: enabled I tested the endpoint directly. GLM successfully generated a valid tool call, interpreted the successful tool result, and returned
finish_reason: stop
. I also inspected the persisted OpenHands trajectory for conversation
c6c1556be42244ff9eb172002de76985
. The agent repeatedly executed the same valid Python terminal command. Every execution succeeded with exit code 0 and returned the same directory listing. After repeated actions, the SDK detected an action/observation loop and marked the conversation STUCK. This conversation had zero condensation events, so condensation isn't required to reproduce the problem. I've also confirmed SDK 1.54.0 already contains the action-error nudge mechanism from #4332, but successful repeated action/observation loops still terminate as STUCK. I'm now checking the actual vLLM launch configuration, including quantization,
glm47
parser settings and streaming behavior, before changing anything. Would you recommend testing the existing NVFP4 serving configuration first, or comparing against FP8 with an identical trajectory? I can share a sanitized trajectory containing the repeated actions and observations. Thanks again for investigating!
m
Hey @strong-knife-73744 sorry for the late answer. Do you still have this problem? Our earlier fix: it was not vLLM-related. We were running GLM-5.2 through OpenRouter, the cheapest provider served it at FP4, and the agent looped on malformed file_editor calls. Forcing FP8 providers made the same task pass. So it was endpoint quantization, not streaming, tool-call formatting, or context handling. Also, that was an error loop, which is what the #4332 nudge covers. Your loop is a valid, successful call, and in SDK 1.54.0 four identical successful action/observation pairs go straight to STUCK with no nudge. Agent Canvas 1.27.1 hardcodes stuck detection on and the agent-server ignores custom thresholds, so there is nothing to tune on that side. #5707/#5783 only touch the TypeScript client, which Canvas doesn't use, and #3112 is unrelated. NVFP4 vs FP8: FP8 won't fit on your hardware. GLM-5.3 Flash is 320B params, FP8 weights are ~306 GiB, and two Sparks have 256 GB. So test the NVFP4 stack first, but as a replay: rebuild the exact /v1/chat/completions request at the step of the first duplicate call from your trajectory, send it to vLLM a few times, and see if the model re-issues the same command. Read its reasoning_content too: it tells you whether it actually sees the earlier tool result. If it reproduces, bisect one change at a time: temperature 1.0 (Z.ai's own setting; 0.2 is low for GLM), DFlash2 off, KV cache to BF16 if you use --kv-cache-dtype fp8 (there is a DGX Spark report of uncalibrated FP8 KV cache causing repetition loops on long sequences), prefix caching off. For the FP8 reference, send the same replayed request to Z.ai's hosted GLM-5.3 Flash endpoint. Also diff your launch flags against the official vLLM recipe: --tool-call-parser glm47 --reasoning-parser glm47 --enable-auto-tool-choice. One more SDK fact: the SDK only sends reasoning_content back to an allow-list of models (Kimi, DeepSeek, MiniMax), not GLM, so the model loses its prior thinking between tool calls. No evidence that this causes your loop, but it's a known gap (#6100, #5399, PR #4446). Please share the sanitized trajectory, your exact vllm serve command, and the vLLM version.