@tiens.nguyen/gonext-local-worker 1.0.193 → 1.0.195
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 +60 -1
- package/package.json +1 -1
package/gonext_agent_chat.py
CHANGED
|
@@ -1800,6 +1800,41 @@ def _ws_for_path(path: str):
|
|
|
1800
1800
|
return None
|
|
1801
1801
|
|
|
1802
1802
|
|
|
1803
|
+
def _workspace_overview(roots, max_entries: int = 40) -> str:
|
|
1804
|
+
"""Cheap, LOCAL top-level listing of each registered workspace root — a plain
|
|
1805
|
+
os.listdir(), no recursion, no network call, no model call. Used two ways: (1)
|
|
1806
|
+
injected into the task prompt so the agent has upfront grounding that the workspace
|
|
1807
|
+
is non-empty WITHOUT spending its first (possibly failing) tool-call round-trip just
|
|
1808
|
+
discovering that; (2) appended to the degrade-to-plain-reply message so even a TOTAL
|
|
1809
|
+
coding-model outage still shows the user their files are actually there — this is
|
|
1810
|
+
the one piece of workspace context that stays available no matter how badly the
|
|
1811
|
+
model-calling side of the agent is failing, since it never touches a model at all."""
|
|
1812
|
+
import os
|
|
1813
|
+
parts = []
|
|
1814
|
+
for w in roots:
|
|
1815
|
+
root = w["path"]
|
|
1816
|
+
try:
|
|
1817
|
+
entries = sorted(
|
|
1818
|
+
e for e in os.listdir(root) if e not in _RAG_SKIP_DIRS
|
|
1819
|
+
)
|
|
1820
|
+
except OSError as e:
|
|
1821
|
+
parts.append(f"{w['name']} ({root}): could not list ({e})")
|
|
1822
|
+
continue
|
|
1823
|
+
if not entries:
|
|
1824
|
+
parts.append(f"{w['name']} ({root}): EMPTY — no files or folders found.")
|
|
1825
|
+
continue
|
|
1826
|
+
shown = entries[:max_entries]
|
|
1827
|
+
labeled = [
|
|
1828
|
+
f"{e}/" if os.path.isdir(os.path.join(root, e)) else e for e in shown
|
|
1829
|
+
]
|
|
1830
|
+
more = f" …(+{len(entries) - max_entries} more)" if len(entries) > max_entries else ""
|
|
1831
|
+
parts.append(
|
|
1832
|
+
f"{w['name']} ({root}) — {len(entries)} top-level item(s): "
|
|
1833
|
+
+ ", ".join(labeled) + more
|
|
1834
|
+
)
|
|
1835
|
+
return "\n".join(parts)
|
|
1836
|
+
|
|
1837
|
+
|
|
1803
1838
|
def _ws_write_allowed(path: str) -> str:
|
|
1804
1839
|
"""Resolve `path` for WRITING: must be inside a registered workspace and never
|
|
1805
1840
|
inside its .git/ internals (agents must not corrupt version control)."""
|
|
@@ -2347,8 +2382,15 @@ def run_agent_chat(cfg):
|
|
|
2347
2382
|
"If the user adds information, rag_add(source_url=url, text=...).\n"
|
|
2348
2383
|
) if _RAG_AVAILABLE else ""
|
|
2349
2384
|
_ws_names = ", ".join(f"{w['name']} = {w['path']}" for w in _WS_ROOTS)
|
|
2385
|
+
# Upfront, ZERO-COST (no tool call, no model round-trip) top-level listing — so the
|
|
2386
|
+
# agent already knows the workspace is non-empty and roughly what's in it before its
|
|
2387
|
+
# first step, instead of having to spend (and risk losing to a timeout) a whole
|
|
2388
|
+
# round-trip just calling list_dir to discover that.
|
|
2389
|
+
_ws_overview = _workspace_overview(_WS_ROOTS) if _WS_AVAILABLE else ""
|
|
2350
2390
|
_ws_tool_block = (
|
|
2351
2391
|
f" WORKSPACES (local code folders you may READ and EDIT): {_ws_names}\n"
|
|
2392
|
+
f" Current contents:\n"
|
|
2393
|
+
+ "\n".join(f" {line}" for line in _ws_overview.splitlines()) + "\n"
|
|
2352
2394
|
" - list_dir(path) / read_text_file(path) — browse and read files.\n"
|
|
2353
2395
|
" - grep_repo(pattern, path='', glob='') — search code, returns file:line hits. "
|
|
2354
2396
|
"Use this to find the EXACT lines to change.\n"
|
|
@@ -3929,7 +3971,24 @@ def run_agent_chat(cfg):
|
|
|
3929
3971
|
# a fabricated "final" answer here instead would poison every future turn's
|
|
3930
3972
|
# prompt with raw exception text (this is exactly what caused task #35).
|
|
3931
3973
|
raise e
|
|
3932
|
-
|
|
3974
|
+
# _plain_reply has NO tool/file/HTTP access whatsoever — that's by design (it's a
|
|
3975
|
+
# bare chat completion). Without a note here, its honest "I don't have access to
|
|
3976
|
+
# your workspace/that page/etc." reads to the user as a PERMISSIONS bug, when the
|
|
3977
|
+
# real cause is that the tool-capable agent loop failed upstream (e.g. the coding
|
|
3978
|
+
# model timed out) and we silently swapped in a capability-limited fallback. Make
|
|
3979
|
+
# that swap visible so the user can tell "genuinely no access" apart from
|
|
3980
|
+
# "the real attempt never got to run" (seen live: workspace summarize request →
|
|
3981
|
+
# coding model timed out 3x on a slow/unreachable remote Ollama box → silent
|
|
3982
|
+
# fallback claimed "no access to your workspace").
|
|
3983
|
+
note = f"⚠️ I couldn't finish the full investigation ({_clip(str(e), 120)}) — here's what I can say without it:\n\n{fallback}"
|
|
3984
|
+
# Append the workspace's ACTUAL top-level contents (computed locally, no model
|
|
3985
|
+
# call — see _workspace_overview) so the user sees their files are really there
|
|
3986
|
+
# even during a total coding-model outage, instead of trusting a plain-chat
|
|
3987
|
+
# model's guess that "there's no code or project" (seen live — false: the
|
|
3988
|
+
# workspace had real content the whole time, the model just never reached it).
|
|
3989
|
+
if _WS_AVAILABLE:
|
|
3990
|
+
note += f"\n\n(Your registered workspace:\n{_workspace_overview(_WS_ROOTS)})"
|
|
3991
|
+
_emit({"type": "final", "text": note})
|
|
3933
3992
|
|
|
3934
3993
|
|
|
3935
3994
|
def _log(text: str):
|
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.195",
|
|
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",
|