@tiens.nguyen/gonext-local-worker 1.0.126 → 1.0.128
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 +53 -1
- package/package.json +1 -1
package/gonext_agent_chat.py
CHANGED
|
@@ -23,6 +23,7 @@ import contextlib
|
|
|
23
23
|
import json
|
|
24
24
|
import re
|
|
25
25
|
import sys
|
|
26
|
+
import time
|
|
26
27
|
import traceback
|
|
27
28
|
import urllib.request
|
|
28
29
|
import urllib.error
|
|
@@ -1270,6 +1271,10 @@ def run_agent_chat(cfg):
|
|
|
1270
1271
|
"- If a response starts with 'HTTP 2' it SUCCEEDED — answer with it next step.\n"
|
|
1271
1272
|
"- NEVER pass an 'Error:' / HTTP 4xx / 5xx result to final_answer. On an error, try a "
|
|
1272
1273
|
"DIFFERENT approach next step (e.g. web_search); only give up after a few tries.\n"
|
|
1274
|
+
"- CONVERGE — do NOT keep searching for a 'more complete' or 'perfect' source; a single "
|
|
1275
|
+
"clean one often does not exist. After 1-2 searches/fetches, COMPILE what you have and "
|
|
1276
|
+
"finish: if a PDF was asked for, call create_pdf(text=<your compiled text>, title=...); "
|
|
1277
|
+
"otherwise call final_answer. NEVER repeat a web_search/fetch_url you already ran.\n"
|
|
1273
1278
|
"- Do NOT put final_answer outside the code block.\n\n"
|
|
1274
1279
|
)
|
|
1275
1280
|
# Lead with the TASK so the weak model anchors on what's actually being asked —
|
|
@@ -1289,6 +1294,26 @@ def run_agent_chat(cfg):
|
|
|
1289
1294
|
# tool returned (no extra model call) if the loop ends without final_answer.
|
|
1290
1295
|
_last_obs: dict = {"text": ""}
|
|
1291
1296
|
|
|
1297
|
+
# Deterministic loop-breaker. Weak models often repeat the SAME search/fetch over and
|
|
1298
|
+
# over (hoping for a "more complete" result) and never converge, burning the whole step
|
|
1299
|
+
# budget. We remember each (tool, arg) signature; on a repeat we DON'T re-run it —
|
|
1300
|
+
# instead we return the prior result plus a hard nudge to move on (compile / create_pdf
|
|
1301
|
+
# / final_answer). Keyed to retrieval tools where the loop actually happens.
|
|
1302
|
+
_seen_calls: dict = {}
|
|
1303
|
+
|
|
1304
|
+
def _dedup(tool_name: str, arg: str, next_hint: str):
|
|
1305
|
+
"""Return (is_repeat, message). On a repeat, message steers the model forward."""
|
|
1306
|
+
sig = f"{tool_name}::{(arg or '').strip().lower()}"
|
|
1307
|
+
prior = _seen_calls.get(sig)
|
|
1308
|
+
if prior is not None:
|
|
1309
|
+
_log(f"{tool_name} REPEAT suppressed ({arg[:60]!r}) → nudging model forward")
|
|
1310
|
+
return True, (
|
|
1311
|
+
f"You already ran {tool_name}({arg!r}) — its result is unchanged and shown "
|
|
1312
|
+
f"above. Do NOT call it again. {next_hint}"
|
|
1313
|
+
)
|
|
1314
|
+
_seen_calls[sig] = True
|
|
1315
|
+
return False, ""
|
|
1316
|
+
|
|
1292
1317
|
@tool
|
|
1293
1318
|
def http_request(method: str, url: str, headers: str = "", body: str = "",
|
|
1294
1319
|
username: str = "", password: str = "") -> str:
|
|
@@ -1381,6 +1406,13 @@ def run_agent_chat(cfg):
|
|
|
1381
1406
|
Args:
|
|
1382
1407
|
query: What to look up, e.g. 'capital of France' or 'productivity day-to-day method'.
|
|
1383
1408
|
"""
|
|
1409
|
+
dup, nudge = _dedup("web_search", query,
|
|
1410
|
+
"Use the facts you have ALREADY gathered: if the task asks for a "
|
|
1411
|
+
"PDF, call create_pdf(text=..., title=...) now; otherwise call "
|
|
1412
|
+
"final_answer with what you found. Do not keep searching for a "
|
|
1413
|
+
"'complete' source — one may not exist.")
|
|
1414
|
+
if dup:
|
|
1415
|
+
return nudge
|
|
1384
1416
|
_emit({"type": "step", "text": f"Searching the web → {query[:80]}"})
|
|
1385
1417
|
result = _web_search_impl(query)
|
|
1386
1418
|
_log(f"web_search {query[:60]!r} → {result[:80]}")
|
|
@@ -1398,6 +1430,12 @@ def run_agent_chat(cfg):
|
|
|
1398
1430
|
Args:
|
|
1399
1431
|
url: The full URL of the page to read, e.g. 'https://example.com/article'.
|
|
1400
1432
|
"""
|
|
1433
|
+
dup, nudge = _dedup("fetch_url", url,
|
|
1434
|
+
"You already have this page's text above. Use it: call "
|
|
1435
|
+
"create_pdf(text=..., title=...) if a PDF was requested, else "
|
|
1436
|
+
"final_answer with what you found.")
|
|
1437
|
+
if dup:
|
|
1438
|
+
return nudge
|
|
1401
1439
|
_emit({"type": "step", "text": f"Reading page → {url[:80]}"})
|
|
1402
1440
|
status, ctype, raw = _fetch_page_impl(url)
|
|
1403
1441
|
if status is None:
|
|
@@ -1627,7 +1665,21 @@ def run_agent_chat(cfg):
|
|
|
1627
1665
|
# 2. strip any leftover Qwen3 <think>…</think> trace (belt-and-suspenders;
|
|
1628
1666
|
# thinking is disabled via /no_think in _prepare_completion_kwargs, but a
|
|
1629
1667
|
# stray trace must never reach the parser or leak to the user).
|
|
1630
|
-
|
|
1668
|
+
# A transient "Connection error" to the local MLX server (seen mid-loop when the
|
|
1669
|
+
# context grows large) otherwise aborts the whole run — retry a couple of times
|
|
1670
|
+
# with a short backoff before giving up.
|
|
1671
|
+
last_err = None
|
|
1672
|
+
for attempt in range(3):
|
|
1673
|
+
try:
|
|
1674
|
+
msg = super().generate(*args, **kwargs)
|
|
1675
|
+
break
|
|
1676
|
+
except Exception as e: # noqa: BLE001
|
|
1677
|
+
last_err = e
|
|
1678
|
+
if attempt < 2:
|
|
1679
|
+
_log(f"generate transient error (attempt {attempt + 1}/3): {e} — retrying")
|
|
1680
|
+
time.sleep(1.5 * (attempt + 1))
|
|
1681
|
+
else:
|
|
1682
|
+
raise last_err
|
|
1631
1683
|
try:
|
|
1632
1684
|
content = getattr(msg, "content", None)
|
|
1633
1685
|
if content is None:
|
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.128",
|
|
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",
|