mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-28 07:57:44 +00:00
fix(loop): prevent step_idx advance on unhandled exceptions + fix consecutive assistant messages
Two bugs that together caused an infinite SKIP loop after LoopResumeError: 1. loop.py _run_step: set step_forward=False in the `else: raise` branch so that when LoopResumeError propagates from _propose (LLMUnavailableError), step_idx stays at 0. Previously it advanced to 1, leaving loops permanently stuck with missing direct_exp_gen result on next resume. 2. base.py _create_chat_completion_auto_continue: when finish_reason=="length" triggers a continuation retry, merge into the previous assistant message instead of appending a second consecutive one. llama-server returns 400 on two consecutive assistant messages, which caused LLMUnavailableError -> LoopResumeError cascade. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -720,7 +720,13 @@ class APIBackend(ABC):
|
||||
|
||||
if finish_reason is None or finish_reason != "length":
|
||||
break # we get a full response now.
|
||||
new_messages.append({"role": "assistant", "content": response})
|
||||
# Merge into the previous assistant message if there already is one at the end.
|
||||
# Appending a second consecutive assistant message causes llama-server to return 400
|
||||
# ("Cannot have 2 or more assistant messages at the end of the list").
|
||||
if new_messages and new_messages[-1]["role"] == "assistant":
|
||||
new_messages[-1]["content"] += response
|
||||
else:
|
||||
new_messages.append({"role": "assistant", "content": response})
|
||||
else:
|
||||
raise RuntimeError(f"Failed to continue the conversation after {try_n} retries.")
|
||||
|
||||
|
||||
@@ -270,6 +270,11 @@ class LoopBase:
|
||||
msg = "We have reset the loop instance, stop all the routines and resume."
|
||||
raise self.LoopResumeError(msg) from e
|
||||
else:
|
||||
# Do NOT advance step_idx for unhandled exceptions (e.g. LoopResumeError
|
||||
# propagating from _propose). Keeping step_idx at the current step lets
|
||||
# kickoff_loop retry step 0 on the next resume instead of permanently
|
||||
# corrupting the loop with a missing direct_exp_gen result.
|
||||
step_forward = False
|
||||
raise # re-raise unhandled exceptions
|
||||
finally:
|
||||
# No matter the execution succeed or not, we have to finish the following steps
|
||||
|
||||
Reference in New Issue
Block a user