@t2000/engine 1.24.13 → 1.25.0

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
@@ -1,9 +1,9 @@
1
+ import * as _t2000_sdk from '@t2000/sdk';
2
+ import { SerializedCetusRoute, PendingReward as PendingReward$1, SwapQuoteResult, T2000 } from '@t2000/sdk';
1
3
  import { z } from 'zod';
2
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
5
  import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
4
6
  import { Tool as Tool$1 } from '@modelcontextprotocol/sdk/types.js';
5
- import * as _t2000_sdk from '@t2000/sdk';
6
- import { PendingReward as PendingReward$1, SwapQuoteResult, T2000 } from '@t2000/sdk';
7
7
 
8
8
  type ProactiveType = 'idle_balance' | 'hf_warning' | 'apy_drift' | 'goal_progress';
9
9
  interface ProactiveMarker {
@@ -1223,6 +1223,12 @@ interface PendingActionStep {
1223
1223
  * `inputCoinFromStep < currentStepIndex` (forward-only references).
1224
1224
  */
1225
1225
  inputCoinFromStep?: number;
1226
+ /**
1227
+ * [SPEC 20.2 / D-1 (a)] Per-step Cetus route — populated for `swap_execute`
1228
+ * steps when a same-turn `swap_quote` matched the step's input. See
1229
+ * `PendingAction.cetusRoute` for the full contract.
1230
+ */
1231
+ cetusRoute?: _t2000_sdk.SerializedCetusRoute;
1226
1232
  }
1227
1233
  /**
1228
1234
  * Serializable description of a write tool that needs user approval.
@@ -1283,6 +1289,25 @@ interface PendingAction {
1283
1289
  * route loops `stepResults` and updates each per-step row.
1284
1290
  */
1285
1291
  attemptId: string;
1292
+ /**
1293
+ * [SPEC 20.2 / D-1 (a)] Cetus route captured at `swap_quote` time and
1294
+ * threaded through to the prepare-route to skip the ~400-500ms
1295
+ * `findSwapRoute()` re-discovery call. Only populated when the same-turn
1296
+ * read pipeline included a successful `swap_quote` whose input matches
1297
+ * this `pending_action`'s amount/from/to (the engine matches at emission
1298
+ * time). Audric's prepare-route validates freshness + coin-type match
1299
+ * before using as fast-path; falls back to fresh discovery on any
1300
+ * mismatch (D-2 structural verification + D-3 TTL re-validation).
1301
+ *
1302
+ * Also rendered into the post-write resume system prompt as a
1303
+ * `<canonical_route>` block (D-4) so LLM narration grounds against the
1304
+ * canonical route — closes S19-F2 (LLM cites stale swap routes).
1305
+ *
1306
+ * **Bundles:** when present on a `steps[]` entry, the per-step
1307
+ * `cetusRoute` takes precedence over the top-level field (which mirrors
1308
+ * `steps[0].cetusRoute` for backward compat with pre-bundle hosts).
1309
+ */
1310
+ cetusRoute?: _t2000_sdk.SerializedCetusRoute;
1286
1311
  /**
1287
1312
  * [SPEC 7 v0.4 Layer 2] When set, this `pending_action` represents a
1288
1313
  * multi-write Payment Intent. Single-step bundles are NOT created — the
@@ -2078,6 +2103,51 @@ declare function bundleShortestTtl(toolUseIds: string[], toolNamesById: Record<s
2078
2103
  /** The set of read tools whose results re-fire on REGENERATE. */
2079
2104
  declare const REGENERATABLE_READ_TOOLS: ReadonlySet<string>;
2080
2105
 
2106
+ /**
2107
+ * [SPEC 20.2 / D-1 (a)] Match a `swap_execute` pending write against the
2108
+ * same-turn `swap_quote` reads to thread the captured Cetus route into
2109
+ * the emitted `pending_action.cetusRoute`.
2110
+ *
2111
+ * The match key is `(from, to, amount, byAmountIn)` — the four fields that
2112
+ * deterministically identify a Cetus route. `slippage` is NOT part of the
2113
+ * key because slippage is a tx-build-time parameter, not a route-discovery
2114
+ * parameter (Cetus's `findSwapRoute` does not take slippage).
2115
+ *
2116
+ * No match → return undefined → caller emits the pending_action without
2117
+ * `cetusRoute`, audric prepare-route falls back to fresh `findSwapRoute()`
2118
+ * (D-5 dual-path). This is the legacy path; correct behavior, just slower.
2119
+ */
2120
+
2121
+ interface SwapQuoteInput {
2122
+ from: string;
2123
+ to: string;
2124
+ amount: number;
2125
+ byAmountIn?: boolean;
2126
+ }
2127
+ interface SwapQuoteResultLike {
2128
+ serializedRoute?: SerializedCetusRoute;
2129
+ }
2130
+ /**
2131
+ * Per-turn read-result entry for swap_quote matching. The engine collects
2132
+ * these alongside the existing `turnReadToolResults` metadata array;
2133
+ * `data` + `input` are populated only for successful `swap_quote` results.
2134
+ */
2135
+ interface SwapQuoteReadEntry {
2136
+ toolUseId: string;
2137
+ input: SwapQuoteInput;
2138
+ result: SwapQuoteResultLike;
2139
+ timestamp: number;
2140
+ }
2141
+ /**
2142
+ * Return the most recent matching `swap_quote`'s serialized route, or
2143
+ * undefined if no same-turn quote matches the swap_execute's input.
2144
+ *
2145
+ * "Most recent" matters when the LLM calls `swap_quote` multiple times in
2146
+ * the same turn (e.g. exploring different amounts) — the most recent
2147
+ * matching quote is the one the user just saw on the quote card.
2148
+ */
2149
+ declare function findMatchingCetusRoute(swapExecuteInput: unknown, swapQuoteReads: SwapQuoteReadEntry[]): SerializedCetusRoute | undefined;
2150
+
2081
2151
  /**
2082
2152
  * [Phase 0 → Phase 3a / SPEC 13] Maximum number of writes per atomic bundle.
2083
2153
  *
@@ -2230,6 +2300,14 @@ interface BundleCompositionInput {
2230
2300
  toolName: string;
2231
2301
  timestamp: number;
2232
2302
  }>;
2303
+ /**
2304
+ * [SPEC 20.2 / D-1 (a)] Same-turn `swap_quote` results paired with their
2305
+ * input + serialized Cetus route. Used to populate `step.cetusRoute` for
2306
+ * any `swap_execute` step whose input matches a quote. Empty / undefined
2307
+ * is fine — the bundle still composes correctly without per-step routes
2308
+ * (audric's prepare-route falls back to fresh `findSwapRoute()`).
2309
+ */
2310
+ swapQuoteReads?: SwapQuoteReadEntry[];
2233
2311
  /** Full assistant message blocks for the deferred turn (engine.ts uses this). */
2234
2312
  assistantContent: ContentBlock[];
2235
2313
  /** Already-resolved tool_result blocks (early-dispatched reads + auto writes). */
@@ -4347,4 +4425,4 @@ declare function getTelemetrySink(): TelemetrySink;
4347
4425
  /** Restore the default noop sink. Used by test teardowns. */
4348
4426
  declare function resetTelemetrySink(): void;
4349
4427
 
4350
- export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, type BundleCompositionInput, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, type DefiCacheEntry, type DefiCacheStore, type DefiProtocol, type DefiSummary, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type EvalSummaryParseResult, type EvaluationItem, type EvaluationStatus, type FetchLock, type FormField, type FormFieldKind, type FormSchema, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, type HarnessShape, type HealthFactorResult, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, type LLMProvider, MAX_BUNDLE_OPS, type McpCallResult, McpClientManager, McpResponseCache, type McpServerConfig, type McpServerConnection, type McpToolAdapterConfig, type McpToolDescriptor, MemorySessionStore, type Message, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, type NaviCacheEntry, type NaviCacheStore, type NaviRawCoin, type NaviRawHealthFactor, type NaviRawPool, type NaviRawPosition, type NaviRawPositionsResponse, type NaviRawProtocolStats, type NaviRawRewardsResponse, type NaviReadOptions, NaviTools, type NormalizedAddress, type OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingActionStep, type PendingInput, type PendingInputState, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PostWritePollOptions, type PostWritePollOutcome, type PostWritePollResult, type PreflightResult, type ProactiveMarker, type ProactiveType, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, type RegenerateFailure, type RegenerateResult, type RegenerateSuccess, type RegenerateTimelineEvent, RetryTracker, type SSEEvent, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, SuinsNotRegisteredError, SuinsRpcError, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, type TelemetrySink, type TelemetryTags, type ThinkingConfig, type ThinkingEffort, type TodoItem$1 as TodoItem, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UpdateTodoInput, type TodoItem as UpdateTodoItem, type UserFinancialProfile, type UserPermissionConfig, VALID_PAIRS, WRITE_TOOLS, type WalletCacheEntry, type WalletCacheStore, type WalletCoin, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, addRecipientTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractAllProactiveMarkers, extractConversationText, extractMcpText, extractTrustedAddressesFromResult, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseProactiveMarker, parseRecipe, parseSSE, payApiTool, pollForIndexerCatchup, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, stripProactiveMarkers, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
4428
+ export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, type BundleCompositionInput, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, type DefiCacheEntry, type DefiCacheStore, type DefiProtocol, type DefiSummary, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type EvalSummaryParseResult, type EvaluationItem, type EvaluationStatus, type FetchLock, type FormField, type FormFieldKind, type FormSchema, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, type HarnessShape, type HealthFactorResult, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, type LLMProvider, MAX_BUNDLE_OPS, type McpCallResult, McpClientManager, McpResponseCache, type McpServerConfig, type McpServerConnection, type McpToolAdapterConfig, type McpToolDescriptor, MemorySessionStore, type Message, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, type NaviCacheEntry, type NaviCacheStore, type NaviRawCoin, type NaviRawHealthFactor, type NaviRawPool, type NaviRawPosition, type NaviRawPositionsResponse, type NaviRawProtocolStats, type NaviRawRewardsResponse, type NaviReadOptions, NaviTools, type NormalizedAddress, type OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingActionStep, type PendingInput, type PendingInputState, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PostWritePollOptions, type PostWritePollOutcome, type PostWritePollResult, type PreflightResult, type ProactiveMarker, type ProactiveType, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, type RegenerateFailure, type RegenerateResult, type RegenerateSuccess, type RegenerateTimelineEvent, RetryTracker, type SSEEvent, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, SuinsNotRegisteredError, SuinsRpcError, type SwapQuoteReadEntry, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, type TelemetrySink, type TelemetryTags, type ThinkingConfig, type ThinkingEffort, type TodoItem$1 as TodoItem, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UpdateTodoInput, type TodoItem as UpdateTodoItem, type UserFinancialProfile, type UserPermissionConfig, VALID_PAIRS, WRITE_TOOLS, type WalletCacheEntry, type WalletCacheStore, type WalletCoin, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, addRecipientTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractAllProactiveMarkers, extractConversationText, extractMcpText, extractTrustedAddressesFromResult, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findMatchingCetusRoute, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseProactiveMarker, parseRecipe, parseSSE, payApiTool, pollForIndexerCatchup, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, stripProactiveMarkers, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
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
  }
@@ -7224,6 +7235,34 @@ var REGENERATABLE_READ_TOOLS = /* @__PURE__ */ new Set([
7224
7235
  "health_check"
7225
7236
  ]);
7226
7237
 
7238
+ // src/swap-route-matching.ts
7239
+ function findMatchingCetusRoute(swapExecuteInput, swapQuoteReads) {
7240
+ if (!isSwapExecuteInput(swapExecuteInput)) return void 0;
7241
+ if (swapQuoteReads.length === 0) return void 0;
7242
+ const target = normalizeSwapKey(swapExecuteInput);
7243
+ for (let i = swapQuoteReads.length - 1; i >= 0; i--) {
7244
+ const entry = swapQuoteReads[i];
7245
+ const candidate = normalizeSwapKey(entry.input);
7246
+ if (candidate.from === target.from && candidate.to === target.to && candidate.amount === target.amount && candidate.byAmountIn === target.byAmountIn) {
7247
+ return entry.result.serializedRoute;
7248
+ }
7249
+ }
7250
+ return void 0;
7251
+ }
7252
+ function isSwapExecuteInput(input) {
7253
+ if (typeof input !== "object" || input === null) return false;
7254
+ const obj = input;
7255
+ return typeof obj.from === "string" && typeof obj.to === "string" && typeof obj.amount === "number";
7256
+ }
7257
+ function normalizeSwapKey(input) {
7258
+ return {
7259
+ from: input.from.toLowerCase(),
7260
+ to: input.to.toLowerCase(),
7261
+ amount: input.amount,
7262
+ byAmountIn: input.byAmountIn ?? true
7263
+ };
7264
+ }
7265
+
7227
7266
  // src/compose-bundle.ts
7228
7267
  var MAX_BUNDLE_OPS = 4;
7229
7268
  var VALID_PAIRS = /* @__PURE__ */ new Set([
@@ -7299,13 +7338,15 @@ function composeBundleFromToolResults(input) {
7299
7338
  }
7300
7339
  const description = describeAction(tool, call);
7301
7340
  const modifiableFields = getModifiableFields(call.name);
7341
+ const cetusRoute = call.name === "swap_execute" && input.swapQuoteReads ? findMatchingCetusRoute(call.input, input.swapQuoteReads) : void 0;
7302
7342
  return {
7303
7343
  toolName: call.name,
7304
7344
  toolUseId: call.id,
7305
7345
  attemptId: randomUUID(),
7306
7346
  input: call.input,
7307
7347
  description,
7308
- ...modifiableFields?.length ? { modifiableFields } : {}
7348
+ ...modifiableFields?.length ? { modifiableFields } : {},
7349
+ ...cetusRoute ? { cetusRoute } : {}
7309
7350
  };
7310
7351
  });
7311
7352
  for (let i = 1; i < input.pendingWrites.length; i++) {
@@ -7338,6 +7379,10 @@ function composeBundleFromToolResults(input) {
7338
7379
  ...allGuardInjections.length ? { guardInjections: allGuardInjections } : {},
7339
7380
  turnIndex: input.turnIndex,
7340
7381
  attemptId: firstStep.attemptId,
7382
+ // [SPEC 20.2 / D-1 (a)] Mirror step[0]'s cetusRoute to the top-level
7383
+ // field for backward compat with pre-bundle hosts that don't iterate
7384
+ // steps[]. Bundle-aware hosts read per-step `step.cetusRoute`.
7385
+ ...firstStep.cetusRoute ? { cetusRoute: firstStep.cetusRoute } : {},
7341
7386
  steps,
7342
7387
  canRegenerate,
7343
7388
  ...quoteAge !== void 0 ? { quoteAge } : {},
@@ -7595,6 +7640,10 @@ var QueryEngine = class {
7595
7640
  })),
7596
7641
  ...writeResultBlocks
7597
7642
  ];
7643
+ const canonicalRouteText = response.approved ? buildCanonicalRouteText(action) : null;
7644
+ if (canonicalRouteText) {
7645
+ allResults.push({ type: "text", text: canonicalRouteText });
7646
+ }
7598
7647
  this.messages.push({ role: "user", content: allResults });
7599
7648
  if (isBundle) {
7600
7649
  const steps = action.steps;
@@ -8144,6 +8193,7 @@ var QueryEngine = class {
8144
8193
  sink.gauge("engine.turn_turns_used", turns, tags);
8145
8194
  };
8146
8195
  const turnReadToolResults = [];
8196
+ const swapQuoteReads = [];
8147
8197
  while (turns < this.maxTurns) {
8148
8198
  if (signal.aborted) {
8149
8199
  yield { type: "error", error: new Error("Aborted") };
@@ -8326,6 +8376,19 @@ ${recipeCtx}`;
8326
8376
  toolName: finalEvent.toolName,
8327
8377
  timestamp: Date.now()
8328
8378
  });
8379
+ if (finalEvent.toolName === "swap_quote" && earlyInput) {
8380
+ const r = finalEvent.result;
8381
+ const dataResult = r?.data && typeof r.data === "object" ? r.data : null;
8382
+ const serializedRoute = r?.serializedRoute ?? dataResult?.serializedRoute;
8383
+ if (serializedRoute) {
8384
+ swapQuoteReads.push({
8385
+ toolUseId: finalEvent.toolUseId,
8386
+ input: earlyInput,
8387
+ result: { serializedRoute },
8388
+ timestamp: Date.now()
8389
+ });
8390
+ }
8391
+ }
8329
8392
  }
8330
8393
  earlyResultBlocks.push({
8331
8394
  type: "tool_result",
@@ -8567,6 +8630,19 @@ ${recipeCtx}`;
8567
8630
  toolName: finalEvent.toolName,
8568
8631
  timestamp: Date.now()
8569
8632
  });
8633
+ if (finalEvent.toolName === "swap_quote" && originalCall) {
8634
+ const r = finalEvent.result;
8635
+ const dataResult = r?.data && typeof r.data === "object" ? r.data : null;
8636
+ const serializedRoute = r?.serializedRoute ?? dataResult?.serializedRoute;
8637
+ if (serializedRoute) {
8638
+ swapQuoteReads.push({
8639
+ toolUseId: finalEvent.toolUseId,
8640
+ input: originalCall.input,
8641
+ result: { serializedRoute },
8642
+ timestamp: Date.now()
8643
+ });
8644
+ }
8645
+ }
8570
8646
  } else {
8571
8647
  this.turnReadCache.clear();
8572
8648
  }
@@ -8717,6 +8793,7 @@ ${recipeCtx}`;
8717
8793
  pendingWrites: guardPassedWrites.map((w) => w.call),
8718
8794
  tools: this.tools,
8719
8795
  readResults: turnReadToolResults,
8796
+ swapQuoteReads,
8720
8797
  assistantContent: acc.assistantBlocks,
8721
8798
  completedResults,
8722
8799
  guardInjectionsByCallId,
@@ -8753,6 +8830,7 @@ ${recipeCtx}`;
8753
8830
  const modifiableFields = getModifiableFields(pendingWrite.call.name);
8754
8831
  const attemptId = randomUUID();
8755
8832
  const singleWriteRegen = computeRegenerateFields(turnReadToolResults);
8833
+ const singleCetusRoute = pendingWrite.call.name === "swap_execute" ? findMatchingCetusRoute(pendingWrite.call.input, swapQuoteReads) : void 0;
8756
8834
  yield {
8757
8835
  type: "pending_action",
8758
8836
  action: {
@@ -8770,6 +8848,7 @@ ${recipeCtx}`;
8770
8848
  ...modifiableFields?.length ? { modifiableFields } : {},
8771
8849
  turnIndex,
8772
8850
  attemptId,
8851
+ ...singleCetusRoute ? { cetusRoute: singleCetusRoute } : {},
8773
8852
  ...singleWriteRegen.canRegenerate ? {
8774
8853
  canRegenerate: true,
8775
8854
  regenerateInput: { toolUseIds: singleWriteRegen.regenerateToolUseIds },
@@ -8921,6 +9000,35 @@ ${recipeCtx}`;
8921
9000
  }
8922
9001
  }
8923
9002
  };
9003
+ function buildCanonicalRouteText(action) {
9004
+ const swaps = [];
9005
+ if (Array.isArray(action.steps) && action.steps.length > 0) {
9006
+ for (const step of action.steps) {
9007
+ if (step.toolName === "swap_execute" && step.cetusRoute) {
9008
+ swaps.push({ input: step.input, cetusRoute: step.cetusRoute });
9009
+ }
9010
+ }
9011
+ } else if (action.toolName === "swap_execute" && action.cetusRoute) {
9012
+ swaps.push({ input: action.input, cetusRoute: action.cetusRoute });
9013
+ }
9014
+ if (swaps.length === 0) return null;
9015
+ const blocks = swaps.map(({ input, cetusRoute }) => {
9016
+ const inp = input;
9017
+ const providers = cetusRoute.routerData.paths.map((p) => p.provider).filter(Boolean).slice(0, 5);
9018
+ const providerLine = providers.length > 0 ? providers.join(" + ") : "Cetus Aggregator";
9019
+ const impactPct = (cetusRoute.priceImpact * 100).toFixed(3);
9020
+ return [
9021
+ "<canonical_route>",
9022
+ `The user just approved a swap. The CANONICAL route taken on-chain is:`,
9023
+ `- Pair: ${inp?.from ?? "?"} \u2192 ${inp?.to ?? "?"}`,
9024
+ `- Path: ${providerLine}`,
9025
+ `- Price impact: ${impactPct}%`,
9026
+ `When narrating this swap, cite this EXACT path string. Do NOT reference any prior swap_quote that produced a different route \u2014 that quote is no longer canonical.`,
9027
+ "</canonical_route>"
9028
+ ].join("\n");
9029
+ });
9030
+ return blocks.join("\n\n");
9031
+ }
8924
9032
  function isCorruptHistoryError(err) {
8925
9033
  const msg = err instanceof Error ? err.message : String(err);
8926
9034
  return msg.includes("tool_use") && msg.includes("tool_result") || msg.includes("roles must alternate") || msg.includes("400") && msg.includes("invalid_request_error");
@@ -10085,31 +10193,48 @@ var AnthropicProvider = class {
10085
10193
  }
10086
10194
  async *chat(params) {
10087
10195
  let attempt = 0;
10088
- while (true) {
10089
- let yieldedAnything = false;
10090
- const inner = this.streamOnce(params);
10091
- try {
10092
- for (; ; ) {
10093
- const next = await inner.next();
10094
- if (next.done) return;
10095
- yieldedAnything = true;
10096
- yield next.value;
10097
- }
10098
- } catch (err) {
10196
+ let success = false;
10197
+ try {
10198
+ while (true) {
10199
+ let yieldedAnything = false;
10200
+ const inner = this.streamOnce(params);
10099
10201
  try {
10100
- await inner.return?.(void 0);
10101
- } catch {
10102
- }
10103
- if (!yieldedAnything && isRetriableError(err) && attempt < this.maxRetries) {
10104
- attempt++;
10105
- const delayMs = computeBackoffMs(attempt);
10106
- console.warn(
10107
- `[anthropic] retriable error (attempt ${attempt}/${this.maxRetries}, retrying in ${delayMs}ms): ${rawErrorMessage(err)}`
10108
- );
10109
- await sleep(delayMs);
10110
- continue;
10202
+ for (; ; ) {
10203
+ const next = await inner.next();
10204
+ if (next.done) {
10205
+ success = true;
10206
+ return;
10207
+ }
10208
+ yieldedAnything = true;
10209
+ yield next.value;
10210
+ }
10211
+ } catch (err) {
10212
+ try {
10213
+ await inner.return?.(void 0);
10214
+ } catch {
10215
+ }
10216
+ if (!yieldedAnything && isRetriableError(err) && attempt < this.maxRetries) {
10217
+ attempt++;
10218
+ const delayMs = computeBackoffMs(attempt);
10219
+ console.warn(
10220
+ `[anthropic] retriable error (attempt ${attempt}/${this.maxRetries}, retrying in ${delayMs}ms): ${rawErrorMessage(err)}`
10221
+ );
10222
+ await sleep(delayMs);
10223
+ continue;
10224
+ }
10225
+ throw new Error(friendlyErrorMessage(err));
10111
10226
  }
10112
- throw new Error(friendlyErrorMessage(err));
10227
+ }
10228
+ } finally {
10229
+ const retried = attempt > 0;
10230
+ const outcome = !retried ? "first_try" : success ? "retried_success" : "exhausted";
10231
+ try {
10232
+ getTelemetrySink().counter("external.retry_count", {
10233
+ vendor: "anthropic",
10234
+ outcome,
10235
+ attempts: String(attempt + 1)
10236
+ });
10237
+ } catch {
10113
10238
  }
10114
10239
  }
10115
10240
  }
@@ -10470,6 +10595,6 @@ function sanitizeAnthropicMessages(messages) {
10470
10595
  return merged;
10471
10596
  }
10472
10597
 
10473
- export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, MAX_BUNDLE_OPS, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, RecipeRegistry, RetryTracker, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SuinsNotRegisteredError, SuinsRpcError, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, TxMutex, VALID_PAIRS, WRITE_TOOLS, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, addRecipientTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractAllProactiveMarkers, extractConversationText, extractMcpText, extractTrustedAddressesFromResult, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseProactiveMarker, parseRecipe, parseSSE, payApiTool, pollForIndexerCatchup, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, stripProactiveMarkers, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
10598
+ export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, MAX_BUNDLE_OPS, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, RecipeRegistry, RetryTracker, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SuinsNotRegisteredError, SuinsRpcError, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, TxMutex, VALID_PAIRS, WRITE_TOOLS, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, addRecipientTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractAllProactiveMarkers, extractConversationText, extractMcpText, extractTrustedAddressesFromResult, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findMatchingCetusRoute, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseProactiveMarker, parseRecipe, parseSSE, payApiTool, pollForIndexerCatchup, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, stripProactiveMarkers, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
10474
10599
  //# sourceMappingURL=index.js.map
10475
10600
  //# sourceMappingURL=index.js.map