@corvio/cli 0.1.0-beta.10 → 0.1.0-beta.11

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.
Files changed (2) hide show
  1. package/dist/cli.js +77 -6
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  agentCredentialPath,
40
40
  } from "./core.js";
41
41
 
42
- const VERSION = "0.1.0-beta.10";
42
+ const VERSION = "0.1.0-beta.11";
43
43
  const DEFAULT_API_BASE = "https://api.corvio.ai/v1";
44
44
  const DEFAULT_APP_BASE = "https://corvio.ai";
45
45
  const USER_AGENT = `corvio-cli/${VERSION}`;
@@ -1628,6 +1628,43 @@ async function startAgentLeaseHeartbeat(api, event, leaseToken, leaseSeconds) {
1628
1628
  };
1629
1629
  }
1630
1630
 
1631
+ const FATAL_AGENT_LISTENER_ERROR_CODES = new Set([
1632
+ "agent_auth_required",
1633
+ "invalid_agent_key",
1634
+ "agent_credential_store_invalid",
1635
+ "agent_routing_ambiguous",
1636
+ "agent_runtime_device_invalid",
1637
+ "agent_runtime_provider_mismatch",
1638
+ "agent_project_binding_required",
1639
+ "agent_provider_unavailable",
1640
+ "agent_provider_not_ready",
1641
+ "agent_handler_required",
1642
+ "agent_handler_failed",
1643
+ "agent_handler_result_invalid",
1644
+ ]);
1645
+
1646
+ function classifyAgentListenerFailure(error) {
1647
+ const code = String(error?.code || "agent_event_processing_failed").trim();
1648
+ const status = Number(error?.status || 0);
1649
+ const fatalListener = error?.exitCode === EXIT.AUTH
1650
+ || status === 401
1651
+ || status === 403
1652
+ || FATAL_AGENT_LISTENER_ERROR_CODES.has(code);
1653
+ const retryable = !fatalListener
1654
+ && (!(status >= 400 && status < 500) || [408, 429].includes(status));
1655
+ return { code, status: status || null, fatalListener, retryable };
1656
+ }
1657
+
1658
+ function attachAgentEventFailure(error, failure) {
1659
+ if (error && typeof error === "object") {
1660
+ error.agentEventFailure = failure;
1661
+ return error;
1662
+ }
1663
+ const wrapped = new CliError(String(error), { code: "agent_event_processing_failed" });
1664
+ wrapped.agentEventFailure = failure;
1665
+ return wrapped;
1666
+ }
1667
+
1631
1668
  async function processClaimedAgentEvent(api, event, options) {
1632
1669
  const leaseToken = String(event?.delivery?.lease_token || "");
1633
1670
  if (!event?.id || !leaseToken) throw new CliError("Claimed event is missing its lease receipt.", { code: "agent_event_invalid" });
@@ -1751,15 +1788,37 @@ async function processClaimedAgentEvent(api, event, options) {
1751
1788
  // The original execution error remains the failure authority.
1752
1789
  }
1753
1790
  }
1791
+ const disposition = classifyAgentListenerFailure(error);
1792
+ let failedEvent = null;
1793
+ let failError = null;
1754
1794
  try {
1755
- await api.request(`/agent-events/${resourcePath(event.id)}:fail`, {
1795
+ failedEvent = await api.request(`/agent-events/${resourcePath(event.id)}:fail`, {
1756
1796
  method: "POST",
1757
- body: { lease_token: leaseToken, error: error instanceof Error ? error.message : String(error), retryable: true },
1797
+ body: {
1798
+ lease_token: leaseToken,
1799
+ error: error instanceof Error ? error.message : String(error),
1800
+ retryable: disposition.retryable,
1801
+ },
1758
1802
  });
1759
- } catch {
1803
+ } catch (failure) {
1804
+ failError = failure;
1760
1805
  // Preserve the original execution failure; the expired lease remains reclaimable.
1761
1806
  }
1762
- throw error;
1807
+ const finalError = failError && classifyAgentListenerFailure(failError).fatalListener
1808
+ ? failError
1809
+ : error;
1810
+ throw attachAgentEventFailure(finalError, {
1811
+ event_id: String(event.id),
1812
+ event: failedEvent,
1813
+ retryable: disposition.retryable,
1814
+ fatal_listener: disposition.fatalListener
1815
+ || Boolean(failError && classifyAgentListenerFailure(failError).fatalListener),
1816
+ error: {
1817
+ code: disposition.code,
1818
+ message: error instanceof Error ? error.message : String(error),
1819
+ ...(disposition.status ? { status: disposition.status } : {}),
1820
+ },
1821
+ });
1763
1822
  }
1764
1823
  }
1765
1824
 
@@ -1773,9 +1832,21 @@ async function runAgent(options) {
1773
1832
  const claimed = await claimAgentEvent(api, options, options.once ? 0 : 30);
1774
1833
  if (!claimed.event) {
1775
1834
  if (options.once) return writeResult({ processed: false, reason: "no_event", retry_after_seconds: claimed.retry_after_seconds }, { json: options.json });
1835
+ const retryAfterSeconds = Number(claimed.retry_after_seconds || 0);
1836
+ if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0) {
1837
+ await sleep(Math.min(30_000, Math.max(50, retryAfterSeconds * 1_000)));
1838
+ }
1839
+ continue;
1840
+ }
1841
+ let receipt;
1842
+ try {
1843
+ receipt = await processClaimedAgentEvent(api, claimed.event, options);
1844
+ } catch (error) {
1845
+ const failure = error?.agentEventFailure;
1846
+ if (options.once || !failure || failure.fatal_listener) throw error;
1847
+ process.stdout.write(`${JSON.stringify({ processed: false, ...failure })}\n`);
1776
1848
  continue;
1777
1849
  }
1778
- const receipt = await processClaimedAgentEvent(api, claimed.event, options);
1779
1850
  if (options.once) return writeResult({ processed: true, ...receipt }, { json: options.json });
1780
1851
  process.stdout.write(`${JSON.stringify({ processed: true, ...receipt })}\n`);
1781
1852
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corvio/cli",
3
- "version": "0.1.0-beta.10",
3
+ "version": "0.1.0-beta.11",
4
4
  "description": "Official Corvio Workspace CLI for questions, knowledge search, documents, and Agent workflows.",
5
5
  "type": "module",
6
6
  "bin": {