@t2000/engine 1.24.12 → 1.24.14

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.js CHANGED
@@ -735,6 +735,13 @@ function cbRecord429(now) {
735
735
  cb429Timestamps = [];
736
736
  }
737
737
  }
738
+ function emitTerminalRetry(vendor, attemptZeroIndexed, outcome) {
739
+ getTelemetrySink().counter("external.retry_count", {
740
+ vendor,
741
+ outcome,
742
+ attempts: String(attemptZeroIndexed + 1)
743
+ });
744
+ }
738
745
  async function fetchBlockVisionWithRetry(url, init, opts = {}) {
739
746
  const rng = opts.rng ?? Math.random;
740
747
  const sleep2 = opts.sleep ?? ((ms) => new Promise((resolve, reject) => {
@@ -780,10 +787,12 @@ async function fetchBlockVisionWithRetry(url, init, opts = {}) {
780
787
  }
781
788
  if (lastResponse.ok) {
782
789
  getTelemetrySink().counter("bv.requests", { status: "2xx", attempt: String(attempt) });
790
+ emitTerminalRetry("bv", attempt, attempt === 0 ? "first_try" : "retried_success");
783
791
  return lastResponse;
784
792
  }
785
793
  if (lastResponse.status !== 429 && lastResponse.status < 500) {
786
794
  getTelemetrySink().counter("bv.requests", { status: String(lastResponse.status), attempt: String(attempt) });
795
+ emitTerminalRetry("bv", attempt, attempt === 0 ? "first_try" : "retried_success");
787
796
  return lastResponse;
788
797
  }
789
798
  if (lastResponse.status === 429) {
@@ -791,12 +800,14 @@ async function fetchBlockVisionWithRetry(url, init, opts = {}) {
791
800
  const now = (opts.now ?? Date.now)();
792
801
  cbRecord429(now);
793
802
  if (cbIsOpen(now)) {
803
+ emitTerminalRetry("bv", attempt, "exhausted");
794
804
  return lastResponse;
795
805
  }
796
806
  } else {
797
807
  getTelemetrySink().counter("bv.requests", { status: "5xx", attempt: String(attempt) });
798
808
  }
799
809
  }
810
+ emitTerminalRetry("bv", BV_RETRY_MAX_ATTEMPTS - 1, "exhausted");
800
811
  if (lastResponse) return lastResponse;
801
812
  throw lastError ?? new Error("fetch failed after retries");
802
813
  }
@@ -7581,7 +7592,10 @@ var QueryEngine = class {
7581
7592
  );
7582
7593
  }
7583
7594
  if (action.assistantContent?.length) {
7584
- this.messages.push({ role: "assistant", content: action.assistantContent });
7595
+ this.messages.push({
7596
+ role: "assistant",
7597
+ content: stripPseudoThinking(action.assistantContent)
7598
+ });
7585
7599
  }
7586
7600
  const allResults = [
7587
7601
  ...(action.completedResults ?? []).map((r) => ({
@@ -7687,7 +7701,7 @@ var QueryEngine = class {
7687
7701
  if (pendingInput.assistantContent.length > 0) {
7688
7702
  this.messages.push({
7689
7703
  role: "assistant",
7690
- content: pendingInput.assistantContent
7704
+ content: stripPseudoThinking(pendingInput.assistantContent)
7691
7705
  });
7692
7706
  }
7693
7707
  const tool = findTool(this.tools, pendingInput.toolName);
@@ -7856,10 +7870,6 @@ var QueryEngine = class {
7856
7870
  blockvisionApiKey: this.blockvisionApiKey,
7857
7871
  portfolioCache: this.portfolioCache
7858
7872
  };
7859
- const canSafetyNet = !!(this.walletAddress && this.suiRpcUrl);
7860
- const safetyNetBaseline = canSafetyNet ? fetchWalletCoins(this.walletAddress, this.suiRpcUrl).then(
7861
- (coins) => new Map(coins.map((c) => [c.coinType, BigInt(c.totalBalance)]))
7862
- ).catch(() => null) : null;
7863
7873
  const cacheInvalidationStart = Date.now();
7864
7874
  if (this.walletAddress) {
7865
7875
  this.portfolioCache?.delete(this.walletAddress);
@@ -7871,8 +7881,7 @@ var QueryEngine = class {
7871
7881
  { has_wallet: this.walletAddress ? "1" : "0" }
7872
7882
  );
7873
7883
  getTelemetrySink().counter("engine.pwr.skipped_sleep_count", {
7874
- has_wallet: this.walletAddress ? "1" : "0",
7875
- can_safety_net: canSafetyNet ? "1" : "0"
7884
+ has_wallet: this.walletAddress ? "1" : "0"
7876
7885
  });
7877
7886
  if (signal.aborted) return;
7878
7887
  const refreshStart = Date.now();
@@ -7978,35 +7987,6 @@ var QueryEngine = class {
7978
7987
  is_bundle: isBundle ? "1" : "0"
7979
7988
  }
7980
7989
  );
7981
- if (safetyNetBaseline && canSafetyNet) {
7982
- const wallet = this.walletAddress;
7983
- const rpc = this.suiRpcUrl;
7984
- void (async () => {
7985
- try {
7986
- const [baseline, current] = await Promise.all([
7987
- safetyNetBaseline,
7988
- fetchWalletCoins(wallet, rpc).then(
7989
- (coins) => new Map(
7990
- coins.map((c) => [c.coinType, BigInt(c.totalBalance)])
7991
- )
7992
- ).catch(() => null)
7993
- ]);
7994
- if (!baseline || !current) return;
7995
- const stale = !walletStateChanged(baseline, current);
7996
- if (stale) {
7997
- getTelemetrySink().counter(
7998
- "engine.pwr.observed_stale_balance_check",
7999
- {
8000
- stale: "1",
8001
- is_bundle: isBundle ? "1" : "0",
8002
- tool_count: String(refreshTools.length)
8003
- }
8004
- );
8005
- }
8006
- } catch {
8007
- }
8008
- })();
8009
- }
8010
7990
  }
8011
7991
  interrupt() {
8012
7992
  this.abortController?.abort();
@@ -8370,14 +8350,20 @@ ${recipeCtx}`;
8370
8350
  const hasEarlyResults = earlyResultBlocks.length > 0;
8371
8351
  const hasRemainingCalls = acc.pendingToolCalls.length > 0;
8372
8352
  if (!hasEarlyResults && !hasRemainingCalls) {
8373
- this.messages.push({ role: "assistant", content: acc.assistantBlocks });
8353
+ this.messages.push({
8354
+ role: "assistant",
8355
+ content: stripPseudoThinking(acc.assistantBlocks)
8356
+ });
8374
8357
  getTelemetrySink().histogram("anthropic.latency_ms", Date.now() - turnStartMs);
8375
8358
  yield { type: "turn_complete", stopReason: acc.stopReason };
8376
8359
  recordTurnOutcome("turn_complete", { stopReason: acc.stopReason });
8377
8360
  return;
8378
8361
  }
8379
8362
  if (signal.aborted) {
8380
- this.messages.push({ role: "assistant", content: acc.assistantBlocks });
8363
+ this.messages.push({
8364
+ role: "assistant",
8365
+ content: stripPseudoThinking(acc.assistantBlocks)
8366
+ });
8381
8367
  if (hasEarlyResults) {
8382
8368
  this.messages.push({ role: "user", content: earlyResultBlocks });
8383
8369
  }
@@ -8683,7 +8669,10 @@ ${recipeCtx}`;
8683
8669
  guardPassedWrites.push(write);
8684
8670
  }
8685
8671
  if (anyGuardBlocked) {
8686
- this.messages.push({ role: "assistant", content: acc.assistantBlocks });
8672
+ this.messages.push({
8673
+ role: "assistant",
8674
+ content: stripPseudoThinking(acc.assistantBlocks)
8675
+ });
8687
8676
  this.messages.push({ role: "user", content: toolResultBlocks });
8688
8677
  getTelemetrySink().counter("engine.turn_outcome", {
8689
8678
  entry: freshPrompt !== null ? "submit" : "resume",
@@ -8714,7 +8703,10 @@ ${recipeCtx}`;
8714
8703
  isError: true
8715
8704
  });
8716
8705
  }
8717
- this.messages.push({ role: "assistant", content: acc.assistantBlocks });
8706
+ this.messages.push({
8707
+ role: "assistant",
8708
+ content: stripPseudoThinking(acc.assistantBlocks)
8709
+ });
8718
8710
  this.messages.push({ role: "user", content: toolResultBlocks });
8719
8711
  getTelemetrySink().counter("engine.turn_outcome", {
8720
8712
  entry: freshPrompt !== null ? "submit" : "resume",
@@ -8799,7 +8791,10 @@ ${recipeCtx}`;
8799
8791
  recordTurnOutcome("pending_action_single");
8800
8792
  return;
8801
8793
  }
8802
- this.messages.push({ role: "assistant", content: acc.assistantBlocks });
8794
+ this.messages.push({
8795
+ role: "assistant",
8796
+ content: stripPseudoThinking(acc.assistantBlocks)
8797
+ });
8803
8798
  this.messages.push({ role: "user", content: toolResultBlocks });
8804
8799
  const toolUseBlocks = acc.assistantBlocks.filter((b) => b.type === "tool_use");
8805
8800
  const allUpdateTodo = toolUseBlocks.length > 0 && toolUseBlocks.every((b) => b.name === "update_todo");
@@ -8937,17 +8932,27 @@ ${recipeCtx}`;
8937
8932
  }
8938
8933
  }
8939
8934
  };
8940
- function walletStateChanged(before, after) {
8941
- if (before.size !== after.size) return true;
8942
- for (const [coinType, balance] of before) {
8943
- if (after.get(coinType) !== balance) return true;
8944
- }
8945
- return false;
8946
- }
8947
8935
  function isCorruptHistoryError(err) {
8948
8936
  const msg = err instanceof Error ? err.message : String(err);
8949
8937
  return msg.includes("tool_use") && msg.includes("tool_result") || msg.includes("roles must alternate") || msg.includes("400") && msg.includes("invalid_request_error");
8950
8938
  }
8939
+ function stripPseudoThinking(blocks) {
8940
+ const out = [];
8941
+ for (const b of blocks) {
8942
+ if (b.type !== "text") {
8943
+ out.push(b);
8944
+ continue;
8945
+ }
8946
+ const stripped = b.text.replace(/<thinking\b[^>]*>[\s\S]*?(?:<\/thinking>|$)/gi, "").trim();
8947
+ if (stripped.length > 0) {
8948
+ out.push({ ...b, text: stripped });
8949
+ }
8950
+ }
8951
+ if (out.length === 0 && blocks.length > 0) {
8952
+ out.push({ type: "text", text: "[narration omitted]" });
8953
+ }
8954
+ return out;
8955
+ }
8951
8956
  function validateHistory(messages) {
8952
8957
  const result = [];
8953
8958
  let i = 0;
@@ -10091,31 +10096,48 @@ var AnthropicProvider = class {
10091
10096
  }
10092
10097
  async *chat(params) {
10093
10098
  let attempt = 0;
10094
- while (true) {
10095
- let yieldedAnything = false;
10096
- const inner = this.streamOnce(params);
10097
- try {
10098
- for (; ; ) {
10099
- const next = await inner.next();
10100
- if (next.done) return;
10101
- yieldedAnything = true;
10102
- yield next.value;
10103
- }
10104
- } catch (err) {
10099
+ let success = false;
10100
+ try {
10101
+ while (true) {
10102
+ let yieldedAnything = false;
10103
+ const inner = this.streamOnce(params);
10105
10104
  try {
10106
- await inner.return?.(void 0);
10107
- } catch {
10108
- }
10109
- if (!yieldedAnything && isRetriableError(err) && attempt < this.maxRetries) {
10110
- attempt++;
10111
- const delayMs = computeBackoffMs(attempt);
10112
- console.warn(
10113
- `[anthropic] retriable error (attempt ${attempt}/${this.maxRetries}, retrying in ${delayMs}ms): ${rawErrorMessage(err)}`
10114
- );
10115
- await sleep(delayMs);
10116
- continue;
10105
+ for (; ; ) {
10106
+ const next = await inner.next();
10107
+ if (next.done) {
10108
+ success = true;
10109
+ return;
10110
+ }
10111
+ yieldedAnything = true;
10112
+ yield next.value;
10113
+ }
10114
+ } catch (err) {
10115
+ try {
10116
+ await inner.return?.(void 0);
10117
+ } catch {
10118
+ }
10119
+ if (!yieldedAnything && isRetriableError(err) && attempt < this.maxRetries) {
10120
+ attempt++;
10121
+ const delayMs = computeBackoffMs(attempt);
10122
+ console.warn(
10123
+ `[anthropic] retriable error (attempt ${attempt}/${this.maxRetries}, retrying in ${delayMs}ms): ${rawErrorMessage(err)}`
10124
+ );
10125
+ await sleep(delayMs);
10126
+ continue;
10127
+ }
10128
+ throw new Error(friendlyErrorMessage(err));
10117
10129
  }
10118
- throw new Error(friendlyErrorMessage(err));
10130
+ }
10131
+ } finally {
10132
+ const retried = attempt > 0;
10133
+ const outcome = !retried ? "first_try" : success ? "retried_success" : "exhausted";
10134
+ try {
10135
+ getTelemetrySink().counter("external.retry_count", {
10136
+ vendor: "anthropic",
10137
+ outcome,
10138
+ attempts: String(attempt + 1)
10139
+ });
10140
+ } catch {
10119
10141
  }
10120
10142
  }
10121
10143
  }