@tiens.nguyen/gonext-local-worker 1.0.75 → 1.0.77
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 +38 -11
- package/package.json +1 -1
package/gonext_agent_chat.py
CHANGED
|
@@ -117,9 +117,31 @@ def _summarise_step(step_log):
|
|
|
117
117
|
return label + (" | ".join(parts) if parts else "thinking…")
|
|
118
118
|
|
|
119
119
|
|
|
120
|
+
# Keywords that strongly indicate the user wants to make an HTTP/network request,
|
|
121
|
+
# regardless of what the final output is (time, text, data, etc.).
|
|
122
|
+
_AGENT_KEYWORDS = re.compile(
|
|
123
|
+
r"\b("
|
|
124
|
+
r"request|fetch|call|hit|ping|curl|wget|GET|POST|PUT|DELETE|PATCH"
|
|
125
|
+
r"|api|endpoint|url|http|https"
|
|
126
|
+
r"|external\s+source|external\s+api|external\s+service"
|
|
127
|
+
r"|web\s+service|rest\s+api|rest\s+call"
|
|
128
|
+
r"|download|scrape|crawl"
|
|
129
|
+
r")\b",
|
|
130
|
+
re.IGNORECASE,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
120
134
|
def _route(task_text: str, base_url: str, api_key: str, model_id: str) -> bool:
|
|
121
|
-
"""
|
|
122
|
-
|
|
135
|
+
"""Decide if the task needs the HTTP agent (True) or a plain chat reply (False).
|
|
136
|
+
|
|
137
|
+
Fast-path: if the user explicitly mentions network/request keywords → agent.
|
|
138
|
+
Otherwise: ask the model to classify.
|
|
139
|
+
"""
|
|
140
|
+
# Fast-path: explicit HTTP/network intent overrides the model classifier.
|
|
141
|
+
if _AGENT_KEYWORDS.search(task_text):
|
|
142
|
+
_log(f"router → YES (keyword match)")
|
|
143
|
+
return True
|
|
144
|
+
|
|
123
145
|
try:
|
|
124
146
|
from openai import OpenAI
|
|
125
147
|
client = OpenAI(base_url=base_url, api_key=api_key or "local",
|
|
@@ -128,12 +150,13 @@ def _route(task_text: str, base_url: str, api_key: str, model_id: str) -> bool:
|
|
|
128
150
|
model=model_id,
|
|
129
151
|
messages=[
|
|
130
152
|
{"role": "system", "content": (
|
|
131
|
-
"You are a task classifier. Reply YES or NO only, no punctuation
|
|
132
|
-
"Answer
|
|
133
|
-
"
|
|
153
|
+
"You are a task classifier. Reply YES or NO only, no punctuation.\n"
|
|
154
|
+
"Answer YES if the task requires fetching data from an external network source "
|
|
155
|
+
"(URL, API, website, web service, or any remote server).\n"
|
|
156
|
+
"Answer NO if it can be solved entirely with Python stdlib, math, or is just conversation."
|
|
134
157
|
)},
|
|
135
158
|
{"role": "user", "content": (
|
|
136
|
-
f"Does this task
|
|
159
|
+
f"Does this task require fetching data from an external network source?\n\n"
|
|
137
160
|
f"Task: {task_text}\n\nYES or NO:"
|
|
138
161
|
)},
|
|
139
162
|
],
|
|
@@ -141,7 +164,7 @@ def _route(task_text: str, base_url: str, api_key: str, model_id: str) -> bool:
|
|
|
141
164
|
temperature=0,
|
|
142
165
|
)
|
|
143
166
|
answer = (resp.choices[0].message.content or "").strip().upper()
|
|
144
|
-
_log(f"router → {answer!r}")
|
|
167
|
+
_log(f"router → {answer!r} (model)")
|
|
145
168
|
return answer.startswith("Y")
|
|
146
169
|
except Exception as e: # noqa: BLE001
|
|
147
170
|
_log(f"router error: {e} — defaulting to agent")
|
|
@@ -249,9 +272,13 @@ def run_agent_chat(cfg):
|
|
|
249
272
|
"It returns a STRING with the HTTP status and body. "
|
|
250
273
|
"Call it, then immediately call `final_answer(response)` inside the same code block.\n"
|
|
251
274
|
"IMPORTANT RULES:\n"
|
|
252
|
-
"-
|
|
253
|
-
"-
|
|
254
|
-
"
|
|
275
|
+
"- `headers` must be a JSON string, e.g. headers='{\"Content-Type\": \"application/json\"}'\n"
|
|
276
|
+
"- For Basic Auth: import base64; "
|
|
277
|
+
"creds = base64.b64encode(b'user:password').decode(); "
|
|
278
|
+
"headers = '{\"Authorization\": \"Basic ' + creds + '\"}'\n"
|
|
279
|
+
"- For Bearer token: headers='{\"Authorization\": \"Bearer YOUR_TOKEN\"}'\n"
|
|
280
|
+
"- Python's `datetime` and `base64` modules are available.\n"
|
|
281
|
+
"- If http_request returns an error starting with 'Error:', do NOT retry the same URL. Try a different one.\n"
|
|
255
282
|
"- Do NOT put final_answer outside the code block.\n\n"
|
|
256
283
|
)
|
|
257
284
|
task_with_hint = tool_hint + "Task: " + task_text
|
|
@@ -340,7 +367,7 @@ def run_agent_chat(cfg):
|
|
|
340
367
|
max_steps=max_steps,
|
|
341
368
|
step_callbacks=[step_callback],
|
|
342
369
|
executor_kwargs={"timeout_seconds": 60},
|
|
343
|
-
additional_authorized_imports=["json", "urllib", "urllib.request", "urllib.error"],
|
|
370
|
+
additional_authorized_imports=["json", "base64", "urllib", "urllib.request", "urllib.error"],
|
|
344
371
|
)
|
|
345
372
|
with contextlib.redirect_stdout(sys.stderr):
|
|
346
373
|
result = agent.run(task_with_hint)
|
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.77",
|
|
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",
|