@t2000/engine 1.25.0 → 1.25.2
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 +66 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3771,6 +3771,34 @@ var swapQuoteTool = buildTool({
|
|
|
3771
3771
|
required: ["from", "to", "amount"]
|
|
3772
3772
|
},
|
|
3773
3773
|
isReadOnly: true,
|
|
3774
|
+
// [SPEC 20.2 / D-1 (a) follow-on, 2026-05-10] Quote results MUST NOT be
|
|
3775
|
+
// cross-turn deduped by microcompact. Every call legitimately produces a
|
|
3776
|
+
// new result — pool reserves move per block, slippage windows update, the
|
|
3777
|
+
// best route can shift if liquidity moves, and the result's `discoveredAt`
|
|
3778
|
+
// timestamp is different per call by definition.
|
|
3779
|
+
//
|
|
3780
|
+
// Pre-fix: microcompact's default `cacheable: true` replaced the second
|
|
3781
|
+
// identical-input swap_quote tool_result with a `[Same result as call #N
|
|
3782
|
+
// — swap_quote with identical inputs. Result unchanged.]` placeholder.
|
|
3783
|
+
// The placeholder lied — the route and `discoveredAt` had legitimately
|
|
3784
|
+
// updated. Audric's bundle fast-path (which reads quote results from the
|
|
3785
|
+
// persisted ledger to thread `step.cetusRoute`) lost the fresh route and
|
|
3786
|
+
// had to fall back to whichever earlier same-input call WAS preserved
|
|
3787
|
+
// (the "first-seen" anchor, often >30s old → rejected by audric's
|
|
3788
|
+
// `isCetusRouteFresh` 30s gate → fast path missed → bundle paid full
|
|
3789
|
+
// ~400-500ms `findSwapRoute()` round-trip at confirm time).
|
|
3790
|
+
//
|
|
3791
|
+
// Production smoke trace (2026-05-10, session s_1778362657811_c0ed9009a5fb):
|
|
3792
|
+
// T0 swap_quote(USDC,SUI,0.5) → route X discovered
|
|
3793
|
+
// T0+34s swap_quote(USDC,SUI,0.5) [bundle] → route Y discovered (FRESH)
|
|
3794
|
+
// T0+50s "Confirm" → fast-path walks history → walker sees placeholder
|
|
3795
|
+
// on route Y, falls back
|
|
3796
|
+
// to route X (52s old)
|
|
3797
|
+
// T0+52s prepare → cetusRoute STALE → fallback → no perf win
|
|
3798
|
+
//
|
|
3799
|
+
// With `cacheable: false`: route Y stays as full content in the ledger,
|
|
3800
|
+
// walker finds it (~18s old), passes the freshness gate, fast path fires.
|
|
3801
|
+
cacheable: false,
|
|
3774
3802
|
async call(input, context) {
|
|
3775
3803
|
const walletAddress = context.agent ? context.agent.address() : getWalletAddress(context);
|
|
3776
3804
|
const sink = getTelemetrySink();
|
|
@@ -7640,7 +7668,7 @@ var QueryEngine = class {
|
|
|
7640
7668
|
})),
|
|
7641
7669
|
...writeResultBlocks
|
|
7642
7670
|
];
|
|
7643
|
-
const canonicalRouteText = response.approved ? buildCanonicalRouteText(action) : null;
|
|
7671
|
+
const canonicalRouteText = response.approved ? buildCanonicalRouteText(action, response) : null;
|
|
7644
7672
|
if (canonicalRouteText) {
|
|
7645
7673
|
allResults.push({ type: "text", text: canonicalRouteText });
|
|
7646
7674
|
}
|
|
@@ -9000,16 +9028,33 @@ ${recipeCtx}`;
|
|
|
9000
9028
|
}
|
|
9001
9029
|
}
|
|
9002
9030
|
};
|
|
9003
|
-
function buildCanonicalRouteText(action) {
|
|
9031
|
+
function buildCanonicalRouteText(action, response) {
|
|
9032
|
+
const failedToolUseIds = /* @__PURE__ */ new Set();
|
|
9033
|
+
if (Array.isArray(action.steps) && action.steps.length > 0) {
|
|
9034
|
+
const stepResultByToolUseId = new Map(
|
|
9035
|
+
(response.stepResults ?? []).map((sr) => [sr.toolUseId, sr])
|
|
9036
|
+
);
|
|
9037
|
+
for (const step of action.steps) {
|
|
9038
|
+
const sr = stepResultByToolUseId.get(step.toolUseId);
|
|
9039
|
+
if (!sr || sr.isError === true) {
|
|
9040
|
+
failedToolUseIds.add(step.toolUseId);
|
|
9041
|
+
}
|
|
9042
|
+
}
|
|
9043
|
+
} else if (isExecutionResultFailure(response.executionResult)) {
|
|
9044
|
+
failedToolUseIds.add(action.toolUseId);
|
|
9045
|
+
}
|
|
9004
9046
|
const swaps = [];
|
|
9005
9047
|
if (Array.isArray(action.steps) && action.steps.length > 0) {
|
|
9006
9048
|
for (const step of action.steps) {
|
|
9007
9049
|
if (step.toolName === "swap_execute" && step.cetusRoute) {
|
|
9050
|
+
if (failedToolUseIds.has(step.toolUseId)) continue;
|
|
9008
9051
|
swaps.push({ input: step.input, cetusRoute: step.cetusRoute });
|
|
9009
9052
|
}
|
|
9010
9053
|
}
|
|
9011
9054
|
} else if (action.toolName === "swap_execute" && action.cetusRoute) {
|
|
9012
|
-
|
|
9055
|
+
if (!failedToolUseIds.has(action.toolUseId)) {
|
|
9056
|
+
swaps.push({ input: action.input, cetusRoute: action.cetusRoute });
|
|
9057
|
+
}
|
|
9013
9058
|
}
|
|
9014
9059
|
if (swaps.length === 0) return null;
|
|
9015
9060
|
const blocks = swaps.map(({ input, cetusRoute }) => {
|
|
@@ -9029,6 +9074,24 @@ function buildCanonicalRouteText(action) {
|
|
|
9029
9074
|
});
|
|
9030
9075
|
return blocks.join("\n\n");
|
|
9031
9076
|
}
|
|
9077
|
+
function isExecutionResultFailure(executionResult) {
|
|
9078
|
+
if (executionResult === null || executionResult === void 0) return false;
|
|
9079
|
+
if (typeof executionResult !== "object") return false;
|
|
9080
|
+
const er = executionResult;
|
|
9081
|
+
if (er.success === false) return true;
|
|
9082
|
+
if (typeof er.error === "string" && er.error.length > 0) return true;
|
|
9083
|
+
if (er._bundleReverted === true) return true;
|
|
9084
|
+
if (er._sessionExpired === true) return true;
|
|
9085
|
+
if (er._txReverted === true) return true;
|
|
9086
|
+
if (er.data && typeof er.data === "object") {
|
|
9087
|
+
const d = er.data;
|
|
9088
|
+
if (typeof d.error === "string" && d.error.length > 0) return true;
|
|
9089
|
+
if (d._bundleReverted === true) return true;
|
|
9090
|
+
if (d._sessionExpired === true) return true;
|
|
9091
|
+
if (d._txReverted === true) return true;
|
|
9092
|
+
}
|
|
9093
|
+
return false;
|
|
9094
|
+
}
|
|
9032
9095
|
function isCorruptHistoryError(err) {
|
|
9033
9096
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9034
9097
|
return msg.includes("tool_use") && msg.includes("tool_result") || msg.includes("roles must alternate") || msg.includes("400") && msg.includes("invalid_request_error");
|