@nexrall/code-core 1.4.5 → 1.4.6

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 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKrH,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAiBlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgBD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CA0alB;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAalD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBhF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKrH,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAiBlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA0BD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CA0alB;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAalD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBhF"}
@@ -25,8 +25,17 @@ function authHeaders() {
25
25
  };
26
26
  }
27
27
  // ─── Retry helpers ────────────────────────────────────────────────────────────
28
- const MAX_RETRIES = 3;
28
+ const MAX_RETRIES = 5;
29
29
  const RETRY_BASE_MS = 1000;
30
+ const RETRY_MAX_MS = 30000;
31
+ /** Exponential backoff with full jitter, capped at RETRY_MAX_MS. The jitter spreads
32
+ * retries out so a fleet of clients hitting the SAME overloaded API (529) don't all
33
+ * reconnect in lockstep and re-trigger the overload (thundering herd). Returns a delay
34
+ * in [exp/2, exp] where exp = min(RETRY_MAX_MS, RETRY_BASE_MS * 2^attempt). */
35
+ function backoffMs(attempt) {
36
+ const exp = Math.min(RETRY_MAX_MS, RETRY_BASE_MS * Math.pow(2, attempt));
37
+ return Math.round(exp / 2 + Math.random() * (exp / 2));
38
+ }
30
39
  function sleep(ms) {
31
40
  return new Promise((r) => setTimeout(r, ms));
32
41
  }
@@ -92,12 +101,12 @@ async function streamChat(messages, options, onEvent) {
92
101
  if (response.status === 429 && attempt < MAX_RETRIES) {
93
102
  reportRetry('Rate limited by the API — retrying');
94
103
  const retryAfter = parseInt(response.headers.get('retry-after') ?? '0', 10);
95
- await sleep(retryAfter > 0 ? retryAfter * 1000 : RETRY_BASE_MS * Math.pow(2, attempt));
104
+ await sleep(retryAfter > 0 ? retryAfter * 1000 : backoffMs(attempt));
96
105
  continue;
97
106
  }
98
107
  if (response.status >= 500 && response.status < 600 && attempt < MAX_RETRIES) {
99
108
  reportRetry(`Server error (${response.status}) — retrying`);
100
- await sleep(RETRY_BASE_MS * Math.pow(2, attempt));
109
+ await sleep(backoffMs(attempt));
101
110
  continue;
102
111
  }
103
112
  // 4xx (incl. 413 Payload Too Large, 400 Bad Request, 402 Insufficient balance)
@@ -115,7 +124,7 @@ async function streamChat(messages, options, onEvent) {
115
124
  // Connection couldn't even be established — network drop / DNS blip / the
116
125
  // machine just woke from sleep and Wi-Fi hasn't reconnected yet.
117
126
  reportRetry('Connection lost — attempting to reconnect');
118
- await sleep(RETRY_BASE_MS * Math.pow(2, attempt));
127
+ await sleep(backoffMs(attempt));
119
128
  continue;
120
129
  }
121
130
  }
@@ -434,7 +443,7 @@ async function streamChat(messages, options, onEvent) {
434
443
  throw err;
435
444
  if (err.retryable && sAttempt < MAX_RETRIES) {
436
445
  reportRetry(err.message || 'Connection interrupted — reconnecting');
437
- await sleep(RETRY_BASE_MS * Math.pow(2, sAttempt));
446
+ await sleep(backoffMs(sAttempt));
438
447
  continue;
439
448
  }
440
449
  throw err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexrall/code-core",
3
- "version": "1.4.5",
3
+ "version": "1.4.6",
4
4
  "description": "Core agent loop, tools, and extension primitives for Nexrall Code — embed an AI coding agent in any Node.js application.",
5
5
  "license": "MIT",
6
6
  "author": "Nexrall <support@nexrall.com> (https://nexrall.com)",