@tiens.nguyen/gonext-local-worker 1.0.184 → 1.0.186
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-repl.mjs +21 -1
- package/gonext_agent_chat.py +24 -8
- package/package.json +1 -1
package/gonext-repl.mjs
CHANGED
|
@@ -43,6 +43,11 @@ const CLEAR_LINE = "\r\x1b[K"; // carriage-return + erase-to-end-of-line
|
|
|
43
43
|
// also drop the worker's ~~~ stream fences (they only matter to the web renderer).
|
|
44
44
|
const isHeartbeatLine = (line) => /…\s?\(\d+s\)\s*$/.test(line);
|
|
45
45
|
const isFenceLine = (line) => line.trim() === "~~~";
|
|
46
|
+
// The model's own raw Python code blob, delimited by <code>/</code> lines in its
|
|
47
|
+
// Thought+Code output. It's redundant with the step summary that follows it (e.g.
|
|
48
|
+
// "Downloading → url"), so we don't print it — only the "Thought:" prose survives.
|
|
49
|
+
const isCodeOpenLine = (line) => line.trim() === "<code>";
|
|
50
|
+
const isCodeCloseLine = (line) => line.trim() === "</code>";
|
|
46
51
|
|
|
47
52
|
// Playful words for the local "thinking…" ticker, reused verbatim from the worker's
|
|
48
53
|
// thinking_words.txt sibling (falls back to a tiny built-in list if it's missing).
|
|
@@ -290,7 +295,10 @@ async function runAgentTurn(history) {
|
|
|
290
295
|
};
|
|
291
296
|
|
|
292
297
|
// Split newly-arrived text into lines: heartbeats + ~~~ fences are swallowed (the ticker
|
|
293
|
-
// shows progress);
|
|
298
|
+
// shows progress); the model's raw <code>…</code> blob is swallowed too (redundant with
|
|
299
|
+
// the step summary that follows it, e.g. "Downloading → url"); blank lines keep spacing;
|
|
300
|
+
// everything else (the "Thought:" prose) commits dim to scrollback.
|
|
301
|
+
let inCode = false;
|
|
294
302
|
const consume = (chunk) => {
|
|
295
303
|
carry += stripThinkTags(chunk);
|
|
296
304
|
let nl;
|
|
@@ -298,6 +306,18 @@ async function runAgentTurn(history) {
|
|
|
298
306
|
const line = carry.slice(0, nl);
|
|
299
307
|
carry = carry.slice(nl + 1);
|
|
300
308
|
if (isHeartbeatLine(line) || isFenceLine(line)) continue; // swallow
|
|
309
|
+
if (!inCode && isCodeOpenLine(line)) {
|
|
310
|
+
// Reasoning just ended and code is about to run — stamp the thought complete,
|
|
311
|
+
// then suppress the code body itself.
|
|
312
|
+
onContent();
|
|
313
|
+
inCode = true;
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (inCode) {
|
|
317
|
+
lastContentAt = Date.now(); // content IS arriving, just not printed
|
|
318
|
+
if (isCodeCloseLine(line)) inCode = false;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
301
321
|
if (line.trim() === "") {
|
|
302
322
|
if (!thinking && !statusShown) process.stdout.write("\n");
|
|
303
323
|
continue;
|
package/gonext_agent_chat.py
CHANGED
|
@@ -488,8 +488,14 @@ def _summarise_step(step_log):
|
|
|
488
488
|
name = getattr(tc, "name", "")
|
|
489
489
|
args = getattr(tc, "arguments", None)
|
|
490
490
|
|
|
491
|
-
if name == "python_interpreter"
|
|
492
|
-
code
|
|
491
|
+
if name == "python_interpreter":
|
|
492
|
+
# smolagents' CodeAgent passes the raw code STRING as `arguments` (NOT a
|
|
493
|
+
# dict — only ToolCallingAgent's structured calls use {"code": ...}). Handle
|
|
494
|
+
# both shapes, else this always fell through to the useless "python_interpreter"
|
|
495
|
+
# label below and never showed what was actually called.
|
|
496
|
+
code = args if isinstance(args, str) else (
|
|
497
|
+
args.get("code", "") if isinstance(args, dict) else ""
|
|
498
|
+
)
|
|
493
499
|
# Show the http_request call if present, else first meaningful line
|
|
494
500
|
m = re.search(r'http_request\s*\(\s*(?:method\s*=\s*)?[\'"]?(\w+)[\'"]?\s*,\s*(?:url\s*=\s*)?[\'"]([^\'"]+)', code)
|
|
495
501
|
if m:
|
|
@@ -514,9 +520,13 @@ def _summarise_step(step_log):
|
|
|
514
520
|
|
|
515
521
|
if observations:
|
|
516
522
|
obs = str(observations).strip()
|
|
517
|
-
# smolagents
|
|
518
|
-
#
|
|
519
|
-
|
|
523
|
+
# smolagents wraps observations as "Execution logs:\n<print output>\nLast output
|
|
524
|
+
# from code snippet:\n<return value>" — both header lines are pure boilerplate.
|
|
525
|
+
# Without filtering "Last output from code snippet:" too, a call with no print()
|
|
526
|
+
# output (most of our @tool functions just `return`, not print) surfaced that
|
|
527
|
+
# HEADER as the shown text instead of the actual return value on the next line.
|
|
528
|
+
_OBS_BOILERPLATE = ("Execution logs:", "Last output from code snippet:")
|
|
529
|
+
lines = [l for l in obs.splitlines() if l.strip() and l.strip() not in _OBS_BOILERPLATE]
|
|
520
530
|
if lines:
|
|
521
531
|
parts.append(f"→ {_clip(lines[0])}")
|
|
522
532
|
|
|
@@ -3277,8 +3287,10 @@ def run_agent_chat(cfg):
|
|
|
3277
3287
|
for dirpath, dirnames, filenames in os.walk(root):
|
|
3278
3288
|
dirnames[:] = [d for d in dirnames if d not in _RAG_SKIP_DIRS]
|
|
3279
3289
|
for fn in filenames:
|
|
3280
|
-
|
|
3281
|
-
|
|
3290
|
+
# ABSOLUTE path — read_file_lines/read_text_file resolve relative
|
|
3291
|
+
# paths against the WORKSPACE root, not whatever subfolder was
|
|
3292
|
+
# listed here, so a name relative to `root` could resolve wrong.
|
|
3293
|
+
entries.append(os.path.join(dirpath, fn))
|
|
3282
3294
|
if len(entries) >= 300:
|
|
3283
3295
|
break
|
|
3284
3296
|
if len(entries) >= 300:
|
|
@@ -3447,7 +3459,11 @@ def run_agent_chat(cfg):
|
|
|
3447
3459
|
with open(abs_path, "r", encoding="utf-8", errors="replace") as fh:
|
|
3448
3460
|
for i, line in enumerate(fh, 1):
|
|
3449
3461
|
if rx.search(line):
|
|
3450
|
-
|
|
3462
|
+
# ABSOLUTE path — read_file_lines/read_text_file resolve
|
|
3463
|
+
# relative paths against the WORKSPACE root, not this
|
|
3464
|
+
# search root, so a path relative to `root` (e.g. when
|
|
3465
|
+
# searching a subfolder) would be silently wrong there.
|
|
3466
|
+
hits.append(f"{abs_path}:{i}: {line.rstrip()[:200]}")
|
|
3451
3467
|
if len(hits) >= 100:
|
|
3452
3468
|
break
|
|
3453
3469
|
except OSError:
|
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.186",
|
|
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",
|