@tiens.nguyen/gonext-local-worker 1.0.178 → 1.0.179

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.
@@ -37,6 +37,33 @@ import urllib.error
37
37
  _REAL_STDOUT = sys.stdout
38
38
 
39
39
 
40
+ # Playful "still thinking" status words shown on the heartbeat while a model call is
41
+ # in flight (see _heartbeat). Loaded once from thinking_words.txt next to this file;
42
+ # a random one is picked per tick so the wait feels alive instead of a fixed string.
43
+ _THINKING_WORDS: list = []
44
+
45
+
46
+ def _thinking_word() -> str:
47
+ """A random playful status word (e.g. 'Caffeinating'). Falls back to a small
48
+ built-in list if thinking_words.txt is missing or empty."""
49
+ import os
50
+ import random
51
+ global _THINKING_WORDS
52
+ if not _THINKING_WORDS:
53
+ try:
54
+ path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "thinking_words.txt")
55
+ with open(path, "r", encoding="utf-8") as fh:
56
+ _THINKING_WORDS = [
57
+ line.strip() for line in fh
58
+ if line.strip() and not line.lstrip().startswith("#")
59
+ ]
60
+ except OSError:
61
+ _THINKING_WORDS = []
62
+ if not _THINKING_WORDS:
63
+ _THINKING_WORDS = ["Thinking", "Percolating", "Caffeinating", "Cogitating"]
64
+ return random.choice(_THINKING_WORDS)
65
+
66
+
40
67
  def _ssl_context():
41
68
  import ssl
42
69
  # Disable cert verification — this agent runs locally against dev tunnels
@@ -1463,6 +1490,10 @@ def _rag_read_allowed(path: str) -> str:
1463
1490
  os.path.realpath(tempfile.gettempdir()),
1464
1491
  os.path.realpath(os.path.join(os.path.expanduser("~"), ".gonext")),
1465
1492
  ] + [w["path"] for w in _WS_ROOTS]
1493
+ # The active terminal folder (download/unzip target) — allow reading what we just
1494
+ # extracted there, even when it isn't a registered workspace.
1495
+ if _WS_ACTIVE:
1496
+ roots.append(_WS_ACTIVE)
1466
1497
  if any(rp == r or rp.startswith(r + os.sep) for r in roots):
1467
1498
  return rp
1468
1499
  raise ValueError(
@@ -1782,20 +1813,31 @@ def run_agent_chat(cfg):
1782
1813
  except Exception: # noqa: BLE001
1783
1814
  continue
1784
1815
  _WS_AVAILABLE = bool(_WS_ROOTS)
1785
- # Active terminal workspace (the `gonext` REPL's launch folder) download_file /
1786
- # unzip_file put their output here. Only honoured if it's a registered workspace
1787
- # root, so it can't redirect writes to an arbitrary folder.
1816
+ # Active terminal workspace: the folder the `gonext` REPL was launched from (sent as
1817
+ # payload.activeWorkspace = the terminal's cwd). download_file / unzip_file put their
1818
+ # output HERE instead of the shared ~/.gonext/rag-work cache, so files land where the
1819
+ # user opened the terminal. Honoured for any real directory the user explicitly opened
1820
+ # the terminal in — these tools already write outside registered workspaces (to
1821
+ # ~/.gonext), so this is not a new write boundary; the code-EDIT tools stay gated on
1822
+ # _WS_ROOTS (registered workspaces) via _ws_write_allowed, unchanged.
1788
1823
  _WS_ACTIVE = ""
1789
- try:
1790
- import os as _os
1791
- aw = _os.path.realpath(_os.path.expanduser(str(cfg.get("activeWorkspace") or "")))
1792
- if aw and _os.path.isdir(aw) and any(
1793
- aw == w["path"] or aw.startswith(w["path"] + _os.sep) for w in _WS_ROOTS
1794
- ):
1795
- _WS_ACTIVE = aw
1796
- _log(f"active workspace: {aw} (download/unzip output → here)")
1797
- except Exception: # noqa: BLE001
1798
- _WS_ACTIVE = ""
1824
+ _aw_raw = str(cfg.get("activeWorkspace") or "").strip()
1825
+ if _aw_raw:
1826
+ try:
1827
+ import os as _os
1828
+ aw = _os.path.realpath(_os.path.expanduser(_aw_raw))
1829
+ if _os.path.isdir(aw):
1830
+ _WS_ACTIVE = aw
1831
+ registered = any(
1832
+ aw == w["path"] or aw.startswith(w["path"] + _os.sep) for w in _WS_ROOTS
1833
+ )
1834
+ _log(f"active workspace: {aw} (download/unzip output → here"
1835
+ f"{'' if registered else '; not a registered workspace — reads/writes here limited to download/unzip'})")
1836
+ else:
1837
+ _log(f"active workspace ignored (not a directory): {aw}")
1838
+ except Exception as _e: # noqa: BLE001
1839
+ _WS_ACTIVE = ""
1840
+ _log(f"active workspace ignored (error resolving '{_aw_raw}'): {_e}")
1799
1841
  if _WS_AVAILABLE:
1800
1842
  _log(f"workspaces: {[(w['name'], w['path'], w['allowRun']) for w in _WS_ROOTS]}")
1801
1843
  # Coding tasks are edit→test→fix loops — 5 steps is too tight. Bump the default
@@ -2766,9 +2808,11 @@ def run_agent_chat(cfg):
2766
2808
  waited = 0
2767
2809
  while not hb_stop.wait(45):
2768
2810
  waited += 45
2811
+ # A random playful word each tick (e.g. "Caffeinating… (90s)") instead
2812
+ # of a fixed "still working" line — a large or cold-loading model can
2813
+ # legitimately take a few minutes on prompt-eval.
2769
2814
  _emit({"type": "step",
2770
- "text": f"Model is still working… ({waited}s — a large or "
2771
- "cold-loading model can take a few minutes)"})
2815
+ "text": f"{_thinking_word()}… ({waited}s)"})
2772
2816
  _log(f"heartbeat: model call in flight {waited}s")
2773
2817
 
2774
2818
  hb = threading.Thread(target=_heartbeat, daemon=True)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiens.nguyen/gonext-local-worker",
3
- "version": "1.0.178",
3
+ "version": "1.0.179",
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",
@@ -28,6 +28,7 @@
28
28
  "gonext_agent_chat.py",
29
29
  "gonext_transcribe.py",
30
30
  "gonext_mlx_embed.py",
31
+ "thinking_words.txt",
31
32
  "README.md",
32
33
  "launchd/"
33
34
  ],
@@ -0,0 +1,106 @@
1
+ # Playful "still thinking / still working" status words for the agent heartbeat.
2
+ # One word/phrase per line; blank lines and lines starting with # are ignored.
3
+ # The worker appends "…" and the elapsed seconds, e.g. "Caffeinating… (90s)".
4
+ Collating
5
+ Caffeinating
6
+ Percolating
7
+ Marinating
8
+ Ruminating
9
+ Cogitating
10
+ Noodling
11
+ Pondering
12
+ Contemplating
13
+ Mulling
14
+ Brewing
15
+ Simmering
16
+ Steeping
17
+ Distilling
18
+ Fermenting
19
+ Incubating
20
+ Marshalling
21
+ Wrangling
22
+ Herding electrons
23
+ Untangling
24
+ Unknotting
25
+ Defragmenting
26
+ Reticulating splines
27
+ Compiling thoughts
28
+ Buffering brilliance
29
+ Warming up the neurons
30
+ Spinning up
31
+ Booting the big brain
32
+ Consulting the oracle
33
+ Summoning tokens
34
+ Conjuring
35
+ Divining
36
+ Calibrating
37
+ Recalibrating
38
+ Triangulating
39
+ Extrapolating
40
+ Interpolating
41
+ Synthesizing
42
+ Crystallizing
43
+ Coalescing
44
+ Assembling
45
+ Stitching
46
+ Weaving
47
+ Knitting
48
+ Threading the needle
49
+ Connecting the dots
50
+ Chasing the thread
51
+ Following the breadcrumbs
52
+ Sifting
53
+ Sieving
54
+ Panning for gold
55
+ Mining
56
+ Excavating
57
+ Spelunking
58
+ Deep-diving
59
+ Surfacing insights
60
+ Percolating harder
61
+ Steeping the tea
62
+ Kneading the dough
63
+ Proofing the loaf
64
+ Letting it rise
65
+ Whisking
66
+ Folding in the facts
67
+ Reducing the sauce
68
+ Plating up
69
+ Garnishing
70
+ Sharpening the pencils
71
+ Oiling the gears
72
+ Greasing the cogs
73
+ Winding the springs
74
+ Charging the flux capacitor
75
+ Aligning the stars
76
+ Consulting the tea leaves
77
+ Reading the room
78
+ Gathering wool
79
+ Chewing it over
80
+ Sleeping on it
81
+ Doing the math
82
+ Carrying the one
83
+ Crunching numbers
84
+ Tallying
85
+ Counting sheep
86
+ Herding cats
87
+ Nudging pixels
88
+ Polishing
89
+ Buffing
90
+ Tuning the antenna
91
+ Finding the signal
92
+ Clearing the static
93
+ Untwisting
94
+ Loosening the knot
95
+ Priming the pump
96
+ Stoking the furnace
97
+ Kindling
98
+ Fanning the embers
99
+ Gathering steam
100
+ Building momentum
101
+ Hatching a plan
102
+ Plotting a course
103
+ Charting the map
104
+ Threading the maze
105
+ Almost there
106
+ Nearly cooked