@tiens.nguyen/gonext-local-worker 1.0.66 → 1.0.68
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 +52 -6
- package/package.json +1 -1
package/gonext_agent_chat.py
CHANGED
|
@@ -146,6 +146,39 @@ def _route(task_text: str, base_url: str, api_key: str, model_id: str) -> bool:
|
|
|
146
146
|
return True
|
|
147
147
|
|
|
148
148
|
|
|
149
|
+
def _summarize_result(task_text: str, agent_output: str,
|
|
150
|
+
base_url: str, api_key: str, model_id: str) -> str:
|
|
151
|
+
"""Always call the model to turn the raw agent output into a clean reply."""
|
|
152
|
+
_log(f"summarizing agent output ({len(agent_output)} chars)")
|
|
153
|
+
try:
|
|
154
|
+
from openai import OpenAI
|
|
155
|
+
client = OpenAI(base_url=base_url, api_key=api_key or "local",
|
|
156
|
+
max_retries=0, timeout=30)
|
|
157
|
+
resp = client.chat.completions.create(
|
|
158
|
+
model=model_id,
|
|
159
|
+
messages=[
|
|
160
|
+
{"role": "system", "content": (
|
|
161
|
+
"You are a helpful assistant. An agent ran HTTP tools to answer the user's "
|
|
162
|
+
"request. Write a clear, concise reply (1-3 sentences) explaining what was "
|
|
163
|
+
"found. Do not include raw code, tool names, or error traces."
|
|
164
|
+
)},
|
|
165
|
+
{"role": "user", "content": (
|
|
166
|
+
f"User asked: {task_text}\n\n"
|
|
167
|
+
f"Agent result: {agent_output[:2000]}\n\n"
|
|
168
|
+
"Reply to the user:"
|
|
169
|
+
)},
|
|
170
|
+
],
|
|
171
|
+
max_tokens=200,
|
|
172
|
+
temperature=0.3,
|
|
173
|
+
)
|
|
174
|
+
summary = (resp.choices[0].message.content or "").strip()
|
|
175
|
+
_log(f"summary: {summary[:120]}")
|
|
176
|
+
return summary or agent_output
|
|
177
|
+
except Exception as e: # noqa: BLE001
|
|
178
|
+
_log(f"summarize error: {e}")
|
|
179
|
+
return agent_output
|
|
180
|
+
|
|
181
|
+
|
|
149
182
|
def _plain_reply(task_text: str, base_url: str, api_key: str, model_id: str) -> str:
|
|
150
183
|
"""Plain chat completion without any tools."""
|
|
151
184
|
try:
|
|
@@ -211,9 +244,16 @@ def run_agent_chat(cfg):
|
|
|
211
244
|
# and always terminate with final_answer() rather than looping forever.
|
|
212
245
|
tool_hint = (
|
|
213
246
|
"You have ONE built-in function: `http_request(method, url, headers='', body='')`. "
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
247
|
+
"It returns a plain STRING — NOT a dict. Never use response['key'] or response.get().\n"
|
|
248
|
+
"The string is either 'HTTP <status>\\n<body>' on success, or 'Error: ...' on failure.\n"
|
|
249
|
+
"Always check for errors first:\n"
|
|
250
|
+
" import json\n"
|
|
251
|
+
" if response.startswith('Error:'):\n"
|
|
252
|
+
" final_answer(f'The request failed: {response}')\n"
|
|
253
|
+
" else:\n"
|
|
254
|
+
" lines = response.split('\\n', 1)\n"
|
|
255
|
+
" data = json.loads(lines[1]) if len(lines) > 1 else {}\n"
|
|
256
|
+
" final_answer(f'The API returned HTTP {lines[0].split()[1]}: {data}')\n\n"
|
|
217
257
|
)
|
|
218
258
|
task_with_hint = tool_hint + "Task: " + task_text
|
|
219
259
|
|
|
@@ -233,9 +273,12 @@ def run_agent_chat(cfg):
|
|
|
233
273
|
parsed_headers = json.loads(headers)
|
|
234
274
|
except Exception: # noqa: BLE001
|
|
235
275
|
pass
|
|
276
|
+
# Retry once on timeout — gorok tunnels can be flaky on the first attempt.
|
|
236
277
|
result = _http_request_impl(method, url, parsed_headers, body or None)
|
|
237
|
-
|
|
238
|
-
|
|
278
|
+
if result.startswith("Error:"):
|
|
279
|
+
_log(f"http_request retry {method.upper()} {url}")
|
|
280
|
+
_emit({"type": "step", "text": f"HTTP {method.upper()} {url} → timeout, retrying…"})
|
|
281
|
+
result = _http_request_impl(method, url, parsed_headers, body or None)
|
|
239
282
|
status_line = result.split("\n")[0][:150] if result else "no response"
|
|
240
283
|
_emit({"type": "step", "text": f"HTTP {method.upper()} {url} → {status_line}"})
|
|
241
284
|
_log(f"http_request {method.upper()} {url} → {result[:80]}")
|
|
@@ -286,7 +329,10 @@ def run_agent_chat(cfg):
|
|
|
286
329
|
)
|
|
287
330
|
with contextlib.redirect_stdout(sys.stderr):
|
|
288
331
|
result = agent.run(task_with_hint)
|
|
289
|
-
final_text =
|
|
332
|
+
final_text = _summarize_result(
|
|
333
|
+
task_text, str(result).strip(),
|
|
334
|
+
agent_base_url, agent_api_key, agent_model_id
|
|
335
|
+
)
|
|
290
336
|
_log(f"done: {len(final_text)} chars")
|
|
291
337
|
_emit({"type": "final", "text": final_text})
|
|
292
338
|
except Exception as e: # noqa: BLE001
|
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.68",
|
|
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",
|