forgexa-cli 1.13.5__tar.gz → 1.13.6__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.13.5
3
+ Version: 1.13.6
4
4
  Summary: Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform
5
5
  Author-email: Jason Sun <dev.winds@gmail.com>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """forgexa-cli — Forgexa command-line client."""
2
- __version__ = "1.13.5"
2
+ __version__ = "1.13.6"
@@ -523,7 +523,7 @@ except (ImportError, ModuleNotFoundError):
523
523
  # DAEMON_VERSION is the protocol/logic version of the daemon code.
524
524
  # Kept in sync with pyproject.toml version via bump-version.sh.
525
525
  # CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
526
- DAEMON_VERSION = "1.13.5"
526
+ DAEMON_VERSION = "1.13.6"
527
527
 
528
528
 
529
529
  def _detect_client_type() -> str:
@@ -1585,6 +1585,14 @@ class WorkspaceManager:
1585
1585
  "connection closed",
1586
1586
  "connection refused",
1587
1587
  "network is unreachable",
1588
+ # DNS resolution failures — transient (network reconnect, DHCP renewal,
1589
+ # macOS resolver flap). macOS/BSD SSH prints "nodename nor servname
1590
+ # provided"; Linux SSH/git prints "name or service not known" or
1591
+ # "temporary failure in name resolution".
1592
+ "nodename nor servname",
1593
+ "name or service not known",
1594
+ "could not resolve host",
1595
+ "temporary failure in name resolution",
1588
1596
  )
1589
1597
  return any(marker in err for marker in retry_markers)
1590
1598
 
@@ -2899,9 +2907,12 @@ class ProcessManager:
2899
2907
  "connection reset",
2900
2908
  "connection timed out",
2901
2909
  "connection error",
2910
+ "failed to get response from the ai model",
2902
2911
  "name or service not known",
2903
2912
  "no such host",
2904
2913
  "network is unreachable",
2914
+ "websockettransporterror",
2915
+ "websocket receive failed",
2905
2916
  # "api error" removed: too broad — matches agent-generated code/output
2906
2917
  # discussing API errors. Real API transport errors are covered by the
2907
2918
  # connection patterns above (refused, reset, timed out, etc.).
@@ -3032,6 +3043,21 @@ class ProcessManager:
3032
3043
  else:
3033
3044
  has_result = True
3034
3045
  has_meaningful_content = True
3046
+ elif ev_type == "session.error":
3047
+ err = data.get("data") or {}
3048
+ if isinstance(err, dict):
3049
+ msg = (
3050
+ err.get("message")
3051
+ or err.get("error")
3052
+ or err.get("errorType")
3053
+ or ""
3054
+ )
3055
+ if msg:
3056
+ error_messages.append(str(msg))
3057
+ elif isinstance(err, str) and err.strip():
3058
+ error_messages.append(err)
3059
+ elif isinstance(data.get("message"), str) and data.get("message", "").strip():
3060
+ error_messages.append(data["message"])
3035
3061
  elif ev_type == "error":
3036
3062
  msg = data.get("message", "")
3037
3063
  if msg:
@@ -4198,7 +4224,27 @@ class ProcessManager:
4198
4224
  # Copilot always exits 0 on normal completion; check result.exitCode
4199
4225
  # from the JSONL "result" event for a true success signal.
4200
4226
  copilot_exit = self._extract_copilot_exit_code(stdout)
4201
- completed_without_result = self._copilot_completed_without_result(stdout)
4227
+ signals = self._extract_output_signals(stdout)
4228
+ completed_without_result = bool(
4229
+ signals["has_turn_completed"]
4230
+ and signals["has_assistant_events"]
4231
+ and signals["has_meaningful_content"]
4232
+ and not signals["has_result"]
4233
+ and not signals["has_turn_failed"]
4234
+ and not signals["error_messages"]
4235
+ )
4236
+ structured_errors = [
4237
+ str(msg).strip()
4238
+ for msg in (signals.get("error_messages") or [])
4239
+ if str(msg).strip()
4240
+ ]
4241
+ copilot_specific_error = ""
4242
+ for msg in reversed(structured_errors):
4243
+ prefix = "Copilot exited with code "
4244
+ suffix = msg[len(prefix):].strip() if msg.startswith(prefix) else ""
4245
+ if not (msg.startswith(prefix) and suffix.isdigit()):
4246
+ copilot_specific_error = msg
4247
+ break
4202
4248
  effective_rc = copilot_exit if copilot_exit is not None else returncode
4203
4249
 
4204
4250
  if effective_rc == 0 and returncode == 0:
@@ -4236,7 +4282,13 @@ class ProcessManager:
4236
4282
  # Retry 2: if still failing AND we haven't already tried both drops,
4237
4283
  # the error is likely auth/quota — log actionable hint.
4238
4284
  _no_tools = not self._copilot_called_any_tools(stdout)
4239
- if effective_rc == 1 and _no_tools and reasoning and not _retry_without_effort:
4285
+ if (
4286
+ effective_rc == 1
4287
+ and _no_tools
4288
+ and reasoning
4289
+ and not _retry_without_effort
4290
+ and not copilot_specific_error
4291
+ ):
4240
4292
  logger.warning(
4241
4293
  "Copilot exitCode=1 with no tool calls for task %s — "
4242
4294
  "retrying without --effort (flag may be unsupported by this CLI version). "
@@ -4248,7 +4300,7 @@ class ProcessManager:
4248
4300
  _retry_without_effort=True,
4249
4301
  )
4250
4302
  # Exhausted retries — emit an actionable diagnostic hint
4251
- if effective_rc == 1 and _no_tools:
4303
+ if effective_rc == 1 and _no_tools and not copilot_specific_error:
4252
4304
  logger.error(
4253
4305
  "Copilot exitCode=1 with no tool calls for task %s after retries. "
4254
4306
  "Likely causes: (1) GitHub auth expired — run `gh auth status` and "
@@ -4257,12 +4309,18 @@ class ProcessManager:
4257
4309
  "To reproduce manually: %s",
4258
4310
  task_id, agent.version, _cmd_display,
4259
4311
  )
4312
+ if copilot_specific_error:
4313
+ failure_error = copilot_specific_error[:1500]
4314
+ elif stderr.strip():
4315
+ failure_error = f"Copilot exited with code {effective_rc}: {stderr[-500:].strip()}"
4316
+ else:
4317
+ failure_error = f"Copilot exited with code {effective_rc}"
4260
4318
  return TaskResult(
4261
4319
  status="failed",
4262
4320
  exit_code=effective_rc,
4263
4321
  stdout=stdout[-settings.AGENT_MAX_OUTPUT_SIZE:],
4264
4322
  stderr=stderr[-10000:],
4265
- error=f"Copilot exited with code {effective_rc}: {stderr[-500:]}",
4323
+ error=failure_error,
4266
4324
  metrics=metrics,
4267
4325
  )
4268
4326
  except asyncio.TimeoutError as exc:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.13.5
3
+ Version: 1.13.6
4
4
  Summary: Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform
5
5
  Author-email: Jason Sun <dev.winds@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "forgexa-cli"
3
- version = "1.13.5"
3
+ version = "1.13.6"
4
4
  description = "Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform"
5
5
  requires-python = ">=3.9"
6
6
  license = { text = "MIT" }
File without changes
File without changes