@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 +94 -72
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
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
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
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
|
-
|
|
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
|
}
|