@t2000/engine 0.46.4 → 0.46.5

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.
package/dist/index.d.ts CHANGED
@@ -1598,13 +1598,17 @@ interface AnthropicProviderConfig {
1598
1598
  apiKey: string;
1599
1599
  defaultModel?: string;
1600
1600
  defaultMaxTokens?: number;
1601
+ /** Max retry attempts for retriable errors (overloaded, rate-limited, network). Default 3. */
1602
+ maxRetries?: number;
1601
1603
  }
1602
1604
  declare class AnthropicProvider implements LLMProvider {
1603
1605
  private client;
1604
1606
  private defaultModel;
1605
1607
  private defaultMaxTokens;
1608
+ private maxRetries;
1606
1609
  constructor(config: AnthropicProviderConfig);
1607
1610
  chat(params: ChatParams): AsyncGenerator<ProviderEvent>;
1611
+ private streamOnce;
1608
1612
  }
1609
1613
 
1610
1614
  declare const CANVAS_TEMPLATES: readonly ["activity_heatmap", "portfolio_timeline", "yield_projector", "health_simulator", "dca_planner", "spending_breakdown", "watch_address", "full_portfolio"];
package/dist/index.js CHANGED
@@ -5729,16 +5729,51 @@ function adaptAllServerTools(manager, serverConfigs) {
5729
5729
  }
5730
5730
  var DEFAULT_MODEL = "claude-sonnet-4-20250514";
5731
5731
  var DEFAULT_MAX_TOKENS2 = 4096;
5732
+ var DEFAULT_MAX_RETRIES = 3;
5733
+ var RETRY_BASE_DELAY_MS = 1e3;
5734
+ var RETRY_MAX_DELAY_MS = 8e3;
5732
5735
  var AnthropicProvider = class {
5733
5736
  client;
5734
5737
  defaultModel;
5735
5738
  defaultMaxTokens;
5739
+ maxRetries;
5736
5740
  constructor(config) {
5737
5741
  this.client = new Anthropic({ apiKey: config.apiKey });
5738
5742
  this.defaultModel = config.defaultModel ?? DEFAULT_MODEL;
5739
5743
  this.defaultMaxTokens = config.defaultMaxTokens ?? DEFAULT_MAX_TOKENS2;
5744
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
5740
5745
  }
5741
5746
  async *chat(params) {
5747
+ let attempt = 0;
5748
+ while (true) {
5749
+ let yieldedAnything = false;
5750
+ const inner = this.streamOnce(params);
5751
+ try {
5752
+ for (; ; ) {
5753
+ const next = await inner.next();
5754
+ if (next.done) return;
5755
+ yieldedAnything = true;
5756
+ yield next.value;
5757
+ }
5758
+ } catch (err) {
5759
+ try {
5760
+ await inner.return?.(void 0);
5761
+ } catch {
5762
+ }
5763
+ if (!yieldedAnything && isRetriableError(err) && attempt < this.maxRetries) {
5764
+ attempt++;
5765
+ const delayMs = computeBackoffMs(attempt);
5766
+ console.warn(
5767
+ `[anthropic] retriable error (attempt ${attempt}/${this.maxRetries}, retrying in ${delayMs}ms): ${rawErrorMessage(err)}`
5768
+ );
5769
+ await sleep(delayMs);
5770
+ continue;
5771
+ }
5772
+ throw new Error(friendlyErrorMessage(err));
5773
+ }
5774
+ }
5775
+ }
5776
+ async *streamOnce(params) {
5742
5777
  const messages = sanitizeAnthropicMessages(
5743
5778
  params.messages.map(toAnthropicMessage)
5744
5779
  );
@@ -5895,6 +5930,59 @@ var AnthropicProvider = class {
5895
5930
  }
5896
5931
  }
5897
5932
  };
5933
+ function isRetriableError(err) {
5934
+ if (!err) return false;
5935
+ if (err instanceof Anthropic.APIError) {
5936
+ if (err.status === 529 || err.status === 408) return true;
5937
+ if (err.status === 502 || err.status === 503 || err.status === 504) return true;
5938
+ if (err.status === 429) return true;
5939
+ return false;
5940
+ }
5941
+ const msg = rawErrorMessage(err).toLowerCase();
5942
+ if (msg.includes("overloaded_error") || msg.includes('"overloaded"') || msg.includes("rate_limit_error") || msg.includes("econnreset") || msg.includes("etimedout") || msg.includes("socket hang up") || msg.includes("fetch failed") || msg.includes("network error")) {
5943
+ return true;
5944
+ }
5945
+ return false;
5946
+ }
5947
+ function rawErrorMessage(err) {
5948
+ if (err instanceof Error) return err.message;
5949
+ if (typeof err === "string") return err;
5950
+ try {
5951
+ return JSON.stringify(err);
5952
+ } catch {
5953
+ return String(err);
5954
+ }
5955
+ }
5956
+ function friendlyErrorMessage(err) {
5957
+ const msg = rawErrorMessage(err).toLowerCase();
5958
+ if (msg.includes("overloaded_error") || msg.includes('"overloaded"') || err instanceof Anthropic.APIError && err.status === 529) {
5959
+ return "Anthropic's servers are over capacity right now. Please try again in 30 seconds.";
5960
+ }
5961
+ if (msg.includes("rate_limit_error") || err instanceof Anthropic.APIError && err.status === 429) {
5962
+ return "Too many requests in a short window. Please wait a moment and try again.";
5963
+ }
5964
+ if (msg.includes("econnreset") || msg.includes("etimedout") || msg.includes("socket hang up") || msg.includes("fetch failed") || msg.includes("network error")) {
5965
+ return "Couldn't reach Anthropic. Check your connection and try again.";
5966
+ }
5967
+ if (err instanceof Anthropic.APIError && err.status === 401) {
5968
+ return "Authentication failed. Please check the Anthropic API key configuration.";
5969
+ }
5970
+ if (err instanceof Anthropic.APIError && err.status === 400) {
5971
+ return "The request was rejected by Anthropic. This is likely a bug \u2014 please retry, and if it persists, contact support.";
5972
+ }
5973
+ if (err instanceof Anthropic.APIError && err.status >= 500) {
5974
+ return "Anthropic returned a server error. Please try again in a moment.";
5975
+ }
5976
+ return "Something went wrong. Please try again.";
5977
+ }
5978
+ function computeBackoffMs(attempt) {
5979
+ const base = Math.min(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1), RETRY_MAX_DELAY_MS);
5980
+ const jitter = Math.floor(Math.random() * 250);
5981
+ return base + jitter;
5982
+ }
5983
+ function sleep(ms) {
5984
+ return new Promise((resolve) => setTimeout(resolve, ms));
5985
+ }
5898
5986
  function toAnthropicSystem(prompt) {
5899
5987
  if (typeof prompt === "string") return prompt;
5900
5988
  return prompt.map((block) => ({