@tiens.nguyen/gonext-local-worker 1.0.79 → 1.0.81

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.
@@ -1376,6 +1376,8 @@ async function runAgentChatJob(job) {
1376
1376
  agentBaseURL: payload?.agentBaseURL ?? "",
1377
1377
  agentApiKey: payload?.agentApiKey ?? "",
1378
1378
  agentModelId: payload?.agentModelId ?? "",
1379
+ codingBaseURL: payload?.codingBaseURL ?? "",
1380
+ codingModelId: payload?.codingModelId ?? "",
1379
1381
  tools: payload?.tools ?? ["http_request"],
1380
1382
  maxSteps: payload?.maxSteps ?? 5,
1381
1383
  });
@@ -8,6 +8,8 @@ Reads on stdin:
8
8
  "agentBaseURL": str,
9
9
  "agentApiKey": str,
10
10
  "agentModelId": str,
11
+ "codingBaseURL": str, # optional: dedicated coding/reasoning model for the
12
+ "codingModelId": str, # CodeAgent's tool-use loop; empty = reuse agentModelId
11
13
  "tools": ["http_request"], # v1: only http_request
12
14
  "maxSteps": int # default 10
13
15
  }
@@ -204,18 +206,27 @@ def _summarize_result(task_text: str, agent_output: str,
204
206
  return agent_output
205
207
 
206
208
 
207
- def _plain_reply(task_text: str, base_url: str, api_key: str, model_id: str) -> str:
208
- """Plain chat completion without any tools."""
209
+ def _plain_reply(messages: list, base_url: str, api_key: str, model_id: str) -> str:
210
+ """Plain chat completion using the full conversation history."""
211
+ _THINK_RE_LOCAL = re.compile(r"<think>.*?</think>", re.DOTALL | re.IGNORECASE)
212
+ chat_messages = [{"role": "system", "content": "You are a helpful assistant."}]
213
+ for m in messages:
214
+ role = m.get("role", "")
215
+ content = m.get("content", "")
216
+ if role not in ("user", "assistant"):
217
+ continue
218
+ if role == "assistant":
219
+ content = _THINK_RE_LOCAL.sub("", content).strip()
220
+ if not content:
221
+ continue
222
+ chat_messages.append({"role": role, "content": content})
209
223
  try:
210
224
  from openai import OpenAI
211
225
  client = OpenAI(base_url=base_url, api_key=api_key or "local",
212
226
  max_retries=0, timeout=60)
213
227
  resp = client.chat.completions.create(
214
228
  model=model_id,
215
- messages=[
216
- {"role": "system", "content": "You are a helpful assistant."},
217
- {"role": "user", "content": task_text},
218
- ],
229
+ messages=chat_messages,
219
230
  temperature=0.7,
220
231
  max_tokens=512,
221
232
  )
@@ -235,9 +246,17 @@ def run_agent_chat(cfg):
235
246
  agent_base_url = cfg.get("agentBaseURL") or ""
236
247
  agent_api_key = cfg.get("agentApiKey") or "local"
237
248
  agent_model_id = cfg.get("agentModelId") or ""
249
+ # Optional dedicated coding/reasoning model for the CodeAgent's tool-use loop.
250
+ # Routing, plain replies and summarization stay on the chat model (better at
251
+ # natural language); the code model only drives http_request reasoning.
252
+ coding_base_url = (cfg.get("codingBaseURL") or "").strip() or agent_base_url
253
+ coding_model_id = (cfg.get("codingModelId") or "").strip() or agent_model_id
238
254
  max_steps = int(cfg.get("maxSteps") or 5)
239
255
 
240
- _log(f"start model={agent_model_id!r} base={agent_base_url!r} maxSteps={max_steps}")
256
+ _log(
257
+ f"start model={agent_model_id!r} base={agent_base_url!r} "
258
+ f"codeModel={coding_model_id!r} codeBase={coding_base_url!r} maxSteps={max_steps}"
259
+ )
241
260
 
242
261
  # Build task from the conversation history.
243
262
  # Include prior USER messages as context so the agent has conversational memory,
@@ -268,7 +287,7 @@ def run_agent_chat(cfg):
268
287
 
269
288
  if not needs_agent:
270
289
  _log("router: plain chat (no HTTP needed)")
271
- answer = _plain_reply(task_text, agent_base_url, agent_api_key, agent_model_id)
290
+ answer = _plain_reply(messages, agent_base_url, agent_api_key, agent_model_id)
272
291
  _log(f"plain reply: {len(answer)} chars")
273
292
  _emit({"type": "final", "text": answer})
274
293
  return
@@ -282,20 +301,24 @@ def run_agent_chat(cfg):
282
301
  tool_hint = (
283
302
  "You have ONE built-in function:\n"
284
303
  " `http_request(method, url, headers='', body='', username='', password='')`\n"
285
- "RETURN FORMAT: the function returns a string like:\n"
286
- " 'HTTP 200\\n{\"key\": \"value\"}'\n"
287
- " First line is 'HTTP <code>' (e.g. 'HTTP 200'). Body follows after the first newline.\n"
288
- "CORRECT USAGEalways just pass response directly to final_answer:\n"
289
- " response = http_request('GET', url)\n"
304
+ "\n"
305
+ "RETURN FORMAT: 'HTTP 200\\n{body}' — first line is 'HTTP <code>', body follows.\n"
306
+ "\n"
307
+ "BASIC AUTHALWAYS use username= and password=, NEVER construct headers manually:\n"
308
+ " response = http_request('GET', 'https://api.example.com/data',\n"
309
+ " username='alice@example.com', password='secret123')\n"
310
+ " final_answer(response)\n"
311
+ "The function handles base64 encoding automatically. NEVER write 'Basic ' + anything.\n"
312
+ "\n"
313
+ "BEARER TOKEN — use headers:\n"
314
+ " response = http_request('GET', url, headers='{\"Authorization\": \"Bearer TOKEN\"}')\n"
290
315
  " final_answer(response)\n"
291
- "Do NOT try to parse or split the response string.\n"
292
- "IMPORTANT RULES:\n"
293
- "- If you get HTTP 2xx (200, 201, etc.) in the first line, the request SUCCEEDED. "
294
- "Call final_answer immediatelydo NOT retry.\n"
295
- "- For Basic Auth: username= and password= params handle encoding automatically.\n"
296
- "- For Bearer token: headers='{\"Authorization\": \"Bearer TOKEN\"}'\n"
297
- "- If http_request returns an error (starts with 'Error:'), try a different URL.\n"
298
- "- Python's `datetime` module is available for date/time tasks.\n"
316
+ "\n"
317
+ "RULES:\n"
318
+ "- Pass response DIRECTLY to final_answer do NOT split, parse, or index the string.\n"
319
+ "- If the response starts with 'HTTP 2' it SUCCEEDED call final_answer immediately.\n"
320
+ "- If http_request returns 'Error:' or HTTP 4xx/5xx, try a different approach.\n"
321
+ "- Python's datetime module is available for date/time tasks (no HTTP needed).\n"
299
322
  "- Do NOT put final_answer outside the code block.\n\n"
300
323
  )
301
324
  task_with_hint = tool_hint + "Task: " + task_text
@@ -385,8 +408,8 @@ def run_agent_chat(cfg):
385
408
 
386
409
  try:
387
410
  model = OpenAIServerModel(
388
- model_id=agent_model_id,
389
- api_base=agent_base_url,
411
+ model_id=coding_model_id,
412
+ api_base=coding_base_url,
390
413
  api_key=agent_api_key,
391
414
  )
392
415
  agent = CodeAgent(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiens.nguyen/gonext-local-worker",
3
- "version": "1.0.79",
3
+ "version": "1.0.81",
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",