@tiens.nguyen/gonext-local-worker 1.0.160 → 1.0.162
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/gonext_agent_chat.py +40 -0
- package/package.json +1 -1
package/gonext_agent_chat.py
CHANGED
|
@@ -2325,6 +2325,26 @@ def run_agent_chat(cfg):
|
|
|
2325
2325
|
in_tok = out_tok = reasoning_len = 0
|
|
2326
2326
|
first_token_at = None
|
|
2327
2327
|
|
|
2328
|
+
# Runaway guard: a degenerate model (seen live: gemma4:26b spewing
|
|
2329
|
+
# "<channel|><thought>" forever) will stream garbage until the client times
|
|
2330
|
+
# out — a multi-minute hang. Abort early if the output either (a) balloons
|
|
2331
|
+
# past a hard char cap, or (b) collapses into a repeating short line. On abort
|
|
2332
|
+
# we return "" so the empty-turn retry re-prompts with the CODE-NOW directive.
|
|
2333
|
+
_MAX_STREAM_CHARS = 16000 # a single agent step never legitimately needs this
|
|
2334
|
+
_stream_buf = [] # every streamed piece (content + reasoning)
|
|
2335
|
+
_stream_chars = 0
|
|
2336
|
+
_runaway = False
|
|
2337
|
+
|
|
2338
|
+
def _looks_runaway() -> bool:
|
|
2339
|
+
tail = "".join(_stream_buf)[-1600:]
|
|
2340
|
+
lines = [ln.strip() for ln in tail.splitlines() if ln.strip()]
|
|
2341
|
+
# 12+ of the last lines are the same short string → degenerate repetition.
|
|
2342
|
+
if len(lines) >= 12:
|
|
2343
|
+
last = lines[-12:]
|
|
2344
|
+
if len(set(last)) <= 2 and all(len(ln) <= 80 for ln in last):
|
|
2345
|
+
return True
|
|
2346
|
+
return False
|
|
2347
|
+
|
|
2328
2348
|
def _mark_first():
|
|
2329
2349
|
# First streamed byte (content OR reasoning). The gap t0→here is pure
|
|
2330
2350
|
# prompt-eval time (server sent nothing before this); everything after is
|
|
@@ -2362,13 +2382,33 @@ def run_agent_chat(cfg):
|
|
|
2362
2382
|
if rpiece:
|
|
2363
2383
|
_mark_first()
|
|
2364
2384
|
reasoning_len += len(rpiece)
|
|
2385
|
+
_stream_buf.append(rpiece)
|
|
2386
|
+
_stream_chars += len(rpiece)
|
|
2365
2387
|
_emit({"type": "stream", "text": rpiece})
|
|
2366
2388
|
piece = getattr(delta, "content", None)
|
|
2367
2389
|
if piece:
|
|
2368
2390
|
_mark_first()
|
|
2369
2391
|
parts.append(piece)
|
|
2392
|
+
_stream_buf.append(piece)
|
|
2393
|
+
_stream_chars += len(piece)
|
|
2370
2394
|
_emit({"type": "stream", "text": piece})
|
|
2395
|
+
# Check the runaway guard periodically (cheap) once enough has streamed.
|
|
2396
|
+
if _stream_chars > 500 and (_stream_chars > _MAX_STREAM_CHARS or _looks_runaway()):
|
|
2397
|
+
_runaway = True
|
|
2398
|
+
reason = "char cap" if _stream_chars > _MAX_STREAM_CHARS else "repeating output"
|
|
2399
|
+
_log(f"streamed generate: ABORTING ({reason}) after {_stream_chars} chars "
|
|
2400
|
+
"— model degenerated; closing stream.")
|
|
2401
|
+
try:
|
|
2402
|
+
stream.close()
|
|
2403
|
+
except Exception: # noqa: BLE001
|
|
2404
|
+
pass
|
|
2405
|
+
break
|
|
2371
2406
|
content = "".join(parts)
|
|
2407
|
+
if _runaway:
|
|
2408
|
+
# Discard the garbage; "" makes _streamed_generate run the CODE-NOW retry.
|
|
2409
|
+
_emit({"type": "step", "text": "Model output ran away — restarting this step…"})
|
|
2410
|
+
_log(f"streamed generate: discarded {len(content)} runaway chars → empty content")
|
|
2411
|
+
return "", role, in_tok, out_tok, reasoning_len
|
|
2372
2412
|
_log(f"streamed generate assembled {len(content)} chars "
|
|
2373
2413
|
f"(in={in_tok} out={out_tok} tokens, reasoning={reasoning_len} chars)")
|
|
2374
2414
|
return content, role, in_tok, out_tok, reasoning_len
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiens.nguyen/gonext-local-worker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.162",
|
|
4
4
|
"description": "Polls GoNext cloud API for async local LLM jobs and runs them against Ollama/OpenAI-compatible servers on this Mac",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|