thebird 1.2.62 → 1.2.64

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.
@@ -4,6 +4,9 @@ function wsStream(url) {
4
4
  const ws = new WebSocket(url);
5
5
  const incoming = [];
6
6
  let notify = null;
7
+ Object.assign(window.__debug = window.__debug || {}, {
8
+ acp: Object.assign(window.__debug?.acp || {}, { wsUrl: url, wsState: 'connecting' })
9
+ });
7
10
  ws.addEventListener('message', e => {
8
11
  const msg = JSON.parse(e.data);
9
12
  if (notify) { const fn = notify; notify = null; fn(msg); }
@@ -11,8 +14,15 @@ function wsStream(url) {
11
14
  });
12
15
  const readable = new ReadableStream({
13
16
  start(ctrl) {
14
- ws.addEventListener('close', () => ctrl.close());
15
- ws.addEventListener('error', e => ctrl.error(e));
17
+ ws.addEventListener('close', () => {
18
+ window.__debug.acp.wsState = 'closed';
19
+ ctrl.close();
20
+ });
21
+ ws.addEventListener('error', e => {
22
+ window.__debug.acp.wsState = 'error';
23
+ window.__debug.acp.wsError = e.message || String(e);
24
+ ctrl.error(e);
25
+ });
16
26
  },
17
27
  pull() {
18
28
  return new Promise(res => {
@@ -25,8 +35,15 @@ function wsStream(url) {
25
35
  write(msg) { ws.send(JSON.stringify(msg)); }
26
36
  });
27
37
  return new Promise((res, rej) => {
28
- ws.addEventListener('open', () => res({ readable, writable }));
29
- ws.addEventListener('error', rej);
38
+ ws.addEventListener('open', () => {
39
+ window.__debug.acp.wsState = 'open';
40
+ res({ readable, writable });
41
+ });
42
+ ws.addEventListener('error', (e) => {
43
+ window.__debug.acp.wsState = 'error';
44
+ window.__debug.acp.wsError = e.message || String(e);
45
+ rej(e);
46
+ });
30
47
  });
31
48
  }
32
49
 
package/docs/app.js CHANGED
@@ -64,6 +64,7 @@ class BirdChat extends HTMLElement {
64
64
 
65
65
  connectedCallback() {
66
66
  this.render();
67
+ Object.assign(window.__debug, { acp: { baseUrl: this.state.baseUrl, provider: this.state.providerType } });
67
68
  if (this.state.apiKey) this.loadModels();
68
69
  }
69
70
 
@@ -18209,6 +18209,19 @@ var require_errors = __commonJS({
18209
18209
  const msg = err?.message ?? "";
18210
18210
  return /quota|rate.?limit|overloaded|unavailable/i.test(msg);
18211
18211
  }
18212
+ function parseRetryDelay(err) {
18213
+ try {
18214
+ const body = typeof err.message === "string" ? JSON.parse(err.message) : err.message;
18215
+ const details = body?.error?.details || [];
18216
+ const retryInfo = details.find((d) => d["@type"]?.includes("RetryInfo"));
18217
+ if (retryInfo?.retryDelay) {
18218
+ const secs = parseFloat(retryInfo.retryDelay);
18219
+ if (!isNaN(secs)) return secs * 1e3;
18220
+ }
18221
+ } catch (_) {
18222
+ }
18223
+ return null;
18224
+ }
18212
18225
  async function withRetry(fn, maxRetries = 3) {
18213
18226
  let lastErr;
18214
18227
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
@@ -18217,7 +18230,8 @@ var require_errors = __commonJS({
18217
18230
  } catch (err) {
18218
18231
  lastErr = err;
18219
18232
  if (!isRetryable(err) || attempt === maxRetries) throw err;
18220
- const delay = Math.min(1e3 * 2 ** attempt + Math.random() * 200, 16e3);
18233
+ const suggested = parseRetryDelay(err);
18234
+ const delay = suggested != null ? suggested + Math.random() * 1e3 : Math.min(1e3 * 2 ** attempt + Math.random() * 200, 16e3);
18221
18235
  await new Promise((r) => setTimeout(r, delay));
18222
18236
  }
18223
18237
  }
package/lib/errors.js CHANGED
@@ -17,6 +17,19 @@ function isRetryable(err) {
17
17
  return /quota|rate.?limit|overloaded|unavailable/i.test(msg);
18
18
  }
19
19
 
20
+ function parseRetryDelay(err) {
21
+ try {
22
+ const body = typeof err.message === 'string' ? JSON.parse(err.message) : err.message;
23
+ const details = body?.error?.details || [];
24
+ const retryInfo = details.find(d => d['@type']?.includes('RetryInfo'));
25
+ if (retryInfo?.retryDelay) {
26
+ const secs = parseFloat(retryInfo.retryDelay);
27
+ if (!isNaN(secs)) return secs * 1000;
28
+ }
29
+ } catch (_) {}
30
+ return null;
31
+ }
32
+
20
33
  async function withRetry(fn, maxRetries = 3) {
21
34
  let lastErr;
22
35
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
@@ -25,7 +38,8 @@ async function withRetry(fn, maxRetries = 3) {
25
38
  } catch (err) {
26
39
  lastErr = err;
27
40
  if (!isRetryable(err) || attempt === maxRetries) throw err;
28
- const delay = Math.min(1000 * 2 ** attempt + Math.random() * 200, 16000);
41
+ const suggested = parseRetryDelay(err);
42
+ const delay = suggested != null ? suggested + Math.random() * 1000 : Math.min(1000 * 2 ** attempt + Math.random() * 200, 16000);
29
43
  await new Promise(r => setTimeout(r, delay));
30
44
  }
31
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thebird",
3
- "version": "1.2.62",
3
+ "version": "1.2.64",
4
4
  "description": "Anthropic SDK to Gemini streaming bridge — drop-in proxy that translates Anthropic message format and tool calls to Google Gemini",
5
5
  "scripts": {
6
6
  "start": "node serve.js"