@t2000/engine 1.11.4 → 1.12.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
@@ -1692,35 +1692,85 @@ declare function bundleShortestTtl(toolUseIds: string[], toolNamesById: Record<s
1692
1692
  declare const REGENERATABLE_READ_TOOLS: ReadonlySet<string>;
1693
1693
 
1694
1694
  /**
1695
- * [F14-fix-2 / 2026-05-03] Maximum number of writes per atomic bundle.
1696
- *
1697
- * The engine refuses to compose a `pending_action` with more than this
1698
- * many steps. Bundles with N > MAX_BUNDLE_OPS get all-step error
1699
- * tool_results synthesized in `engine.ts` so the LLM re-plans into two
1700
- * sequential ≤N-op bundles. Why 5:
1701
- *
1702
- * - Vercel runtime budget. At N>5 writes, Turn 2's emission + guard
1703
- * work + bundle compose has been observed in production to push
1704
- * /api/engine/chat past the 300s `maxDuration`. Reducing the cap
1705
- * keeps every flow well under the timeout.
1706
- * - Quote-freshness coupling. SwapQuoteTracker `windowMs = 60_000`.
1707
- * With N>5 (especially 2+ swap legs), Turn 2's planning + emission
1708
- * routinely bleeds past 60s; the stale-quote guard then blocks
1709
- * swap_execute on legs whose quote went stale during thinking.
1710
- * - LLM working memory. Sonnet+medium has been observed to drop
1711
- * legs when bundling >5 writes (the original B2 incident — LLM
1712
- * asked to emit 6 writes in one Turn 2 emitted only 3).
1713
- * - User cognitive load. A 6+ leg PermissionCard takes 30+ seconds
1714
- * to re-read; capping at 5 keeps the card scannable.
1715
- * - PTB instruction budget. Sui PTB max instructions ~1024; each leg
1716
- * consumes 5–20 instructions. 5 legs 100 instructions well
1717
- * under the cap with comfortable headroom for nested splits.
1718
- *
1719
- * Hosts that want to advertise the cap in system prompts should import
1720
- * this constant rather than hardcoding `5` — bumping the cap in one
1721
- * place keeps host prompts and engine behavior in lockstep.
1722
- */
1723
- declare const MAX_BUNDLE_OPS = 5;
1695
+ * [Phase 0 / SPEC 13 / 2026-05-03] Maximum number of writes per atomic bundle.
1696
+ *
1697
+ * **History.** This was 5 between F14-fix-2 (2026-05-03 morning) and
1698
+ * Phase 0 (2026-05-03 evening). The May 3 production review found that
1699
+ * the underlying problem was never the count bundles fail because
1700
+ * SDK appenders pre-fetch coins from the wallet and the chained asset
1701
+ * doesn't exist there yet (e.g. `swap_execute(USDC→USDsui) +
1702
+ * save_deposit(USDsui)` reverts at PREPARE because USDsui isn't in the
1703
+ * wallet at compose time). SPEC 13 builds the chained-coin handoff
1704
+ * primitive. Until that ships in `1.13.0`, Phase 0 strict-tightens
1705
+ * bundles to:
1706
+ *
1707
+ * - Cap = 2 ops (was 5).
1708
+ * - Every adjacent pair MUST be in `VALID_PAIRS` (was: any 2
1709
+ * bundleable tools).
1710
+ *
1711
+ * **Why 2.** Every multi-write production failure today reduces to
1712
+ * the same gap: a chained-asset bundle whose intermediate output
1713
+ * doesn't exist in the wallet yet. The `VALID_PAIRS` whitelist below
1714
+ * enumerates every (producer, consumer) couple where chaining either
1715
+ * works today (because the consumer takes a wallet coin that the
1716
+ * producer happens to leave there via `tx.transferObjects`) OR will
1717
+ * work after Phase 1. Anything outside the whitelist falls through
1718
+ * to sequential — same outcome the LLM was already producing as a
1719
+ * fallback, just without the wasted PREPARE round-trip.
1720
+ *
1721
+ * **Why not 3+.** 3-op chains require a graph validator (every adjacent
1722
+ * pair valid + DAG topology checks) — that's Phase 2. Cap stays at 2
1723
+ * until Phase 1 lands the validator.
1724
+ *
1725
+ * Hosts importing this constant for system-prompt construction get the
1726
+ * current cap automatically. Bumping the cap in Phase 1 + Phase 2 + …
1727
+ * is a one-line change here that propagates to prompts via the import.
1728
+ */
1729
+ declare const MAX_BUNDLE_OPS = 2;
1730
+ /**
1731
+ * [Phase 0 / SPEC 13] Whitelisted (producer, consumer) pairs for atomic
1732
+ * bundling. Every key has the shape `${producer}->${consumer}`. Bundles
1733
+ * whose adjacent steps aren't in this set get refused with
1734
+ * `_gate: 'pair_not_whitelisted'` so the LLM splits sequentially.
1735
+ *
1736
+ * **The 7 pairs and why they're safe in Phase 0.**
1737
+ *
1738
+ * | Pair | Why it works at compose time today |
1739
+ * |---|---|
1740
+ * | `swap_execute → send_transfer` | Swap's `tx.transferObjects([result.coin], sender)` lands the swap output in the wallet for the same PTB; send's `selectAndSplitCoin` finds it. |
1741
+ * | `swap_execute → save_deposit` | Same mechanism — swap output is back in wallet for save's coin fetch. (P0 caveat: this currently *fails* if the wallet has zero of `swap.to` BEFORE the swap step. Phase 1's `inputCoinFromStep` fixes that. For now we accept the pair but warn the LLM in the prompt rule that wallet must hold ≥0 of target asset.) |
1742
+ * | `swap_execute → repay_debt` | Same as save. Same caveat. |
1743
+ * | `withdraw → swap_execute` | Withdraw's output is transferred to user; swap's coin fetch finds it. Same wallet caveat in reverse. |
1744
+ * | `withdraw → send_transfer` | Same shape. |
1745
+ * | `borrow → send_transfer` | Borrow output lands in wallet; send finds it. |
1746
+ * | `borrow → repay_debt` (same asset) | Unusual but valid — borrow output repays elsewhere. |
1747
+ *
1748
+ * **NOT in the whitelist** (sequential only until Phase 1+):
1749
+ *
1750
+ * - `swap → swap` — chained-asset handoff between two swaps. Phase 3.
1751
+ * - `borrow → swap` — borrow output is `USDC|USDsui`, swap takes any
1752
+ * `from`. Could be added in Phase 1.
1753
+ * - `claim_rewards → *` — produces N reward coins, structurally
1754
+ * different. Phase 5+.
1755
+ * - Anything with `volo_stake` / `volo_unstake` chained — Phase 5+.
1756
+ */
1757
+ declare const VALID_PAIRS: ReadonlySet<string>;
1758
+ /**
1759
+ * Test whether a 2-op bundle's (producer, consumer) pair is in the
1760
+ * Phase 0 whitelist. Returns the pair key on match, `null` otherwise
1761
+ * so callers can include the rejection reason in the synthesized
1762
+ * tool_result.
1763
+ *
1764
+ * Caller is responsible for ensuring `producer` and `consumer` are the
1765
+ * actual tool names of the bundle's two steps (in execution order).
1766
+ */
1767
+ declare function checkValidPair(producer: string, consumer: string): {
1768
+ ok: true;
1769
+ pair: string;
1770
+ } | {
1771
+ ok: false;
1772
+ pair: string;
1773
+ };
1724
1774
 
1725
1775
  /**
1726
1776
  * SPEC 7 v0.3 Quote-Refresh ReviewCard — engine-side bundle regeneration.
@@ -3730,4 +3780,4 @@ declare function getTelemetrySink(): TelemetrySink;
3730
3780
  /** Restore the default noop sink. Used by test teardowns. */
3731
3781
  declare function resetTelemetrySink(): void;
3732
3782
 
3733
- export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, 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 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 PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, 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, WRITE_TOOLS, type WalletCacheEntry, type WalletCacheStore, type WalletCoin, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, 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, parseRecipe, parseSSE, payApiTool, 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, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
3783
+ export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, 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 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 PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, 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, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, 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, parseRecipe, parseSSE, payApiTool, 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, 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
@@ -6732,7 +6732,20 @@ var REGENERATABLE_READ_TOOLS = /* @__PURE__ */ new Set([
6732
6732
  ]);
6733
6733
 
6734
6734
  // src/compose-bundle.ts
6735
- var MAX_BUNDLE_OPS = 5;
6735
+ var MAX_BUNDLE_OPS = 2;
6736
+ var VALID_PAIRS = /* @__PURE__ */ new Set([
6737
+ "swap_execute->send_transfer",
6738
+ "swap_execute->save_deposit",
6739
+ "swap_execute->repay_debt",
6740
+ "withdraw->swap_execute",
6741
+ "withdraw->send_transfer",
6742
+ "borrow->send_transfer",
6743
+ "borrow->repay_debt"
6744
+ ]);
6745
+ function checkValidPair(producer, consumer) {
6746
+ const pair = `${producer}->${consumer}`;
6747
+ return VALID_PAIRS.has(pair) ? { ok: true, pair } : { ok: false, pair };
6748
+ }
6736
6749
  function composeBundleFromToolResults(input) {
6737
6750
  if (input.pendingWrites.length < 2) {
6738
6751
  throw new Error(
@@ -6920,6 +6933,10 @@ var QueryEngine = class {
6920
6933
  async *submitMessage(prompt, options) {
6921
6934
  if (this.costTracker.isOverBudget()) {
6922
6935
  yield { type: "error", error: new Error("Session budget exceeded") };
6936
+ getTelemetrySink().counter("engine.turn_outcome", {
6937
+ entry: "submit",
6938
+ outcome: "error_budget"
6939
+ });
6923
6940
  return;
6924
6941
  }
6925
6942
  this.abortController = new AbortController();
@@ -7058,6 +7075,10 @@ var QueryEngine = class {
7058
7075
  }
7059
7076
  if (!response.approved) {
7060
7077
  yield { type: "turn_complete", stopReason: "end_turn" };
7078
+ getTelemetrySink().counter("engine.turn_outcome", {
7079
+ entry: "resume",
7080
+ outcome: "pending_action_decline"
7081
+ });
7061
7082
  this.turnReadCache.clear();
7062
7083
  return;
7063
7084
  }
@@ -7344,10 +7365,22 @@ var QueryEngine = class {
7344
7365
  let turns = 0;
7345
7366
  let hasRetriedWithCleanHistory = false;
7346
7367
  let turnStartMs = Date.now();
7368
+ const recordTurnOutcome = (outcome, extra = {}) => {
7369
+ const tags = {
7370
+ entry: freshPrompt !== null ? "submit" : "resume",
7371
+ outcome
7372
+ };
7373
+ if (extra.stopReason) tags.stopReason = extra.stopReason;
7374
+ const sink = getTelemetrySink();
7375
+ sink.counter("engine.turn_outcome", tags);
7376
+ sink.histogram("engine.turn_duration_ms", Date.now() - turnStartMs, tags);
7377
+ sink.gauge("engine.turn_turns_used", turns, tags);
7378
+ };
7347
7379
  const turnReadToolResults = [];
7348
7380
  while (turns < this.maxTurns) {
7349
7381
  if (signal.aborted) {
7350
7382
  yield { type: "error", error: new Error("Aborted") };
7383
+ recordTurnOutcome("error_aborted");
7351
7384
  return;
7352
7385
  }
7353
7386
  turns++;
@@ -7532,6 +7565,7 @@ ${recipeCtx}`;
7532
7565
  this.messages.push({ role: "assistant", content: acc.assistantBlocks });
7533
7566
  getTelemetrySink().histogram("anthropic.latency_ms", Date.now() - turnStartMs);
7534
7567
  yield { type: "turn_complete", stopReason: acc.stopReason };
7568
+ recordTurnOutcome("turn_complete", { stopReason: acc.stopReason });
7535
7569
  return;
7536
7570
  }
7537
7571
  if (signal.aborted) {
@@ -7541,6 +7575,7 @@ ${recipeCtx}`;
7541
7575
  }
7542
7576
  this.addErrorResults(acc.pendingToolCalls, "Aborted");
7543
7577
  yield { type: "error", error: new Error("Aborted") };
7578
+ recordTurnOutcome("error_aborted");
7544
7579
  return;
7545
7580
  }
7546
7581
  const approved = [];
@@ -7793,6 +7828,10 @@ ${recipeCtx}`;
7793
7828
  if (anyGuardBlocked) {
7794
7829
  this.messages.push({ role: "assistant", content: acc.assistantBlocks });
7795
7830
  this.messages.push({ role: "user", content: toolResultBlocks });
7831
+ getTelemetrySink().counter("engine.turn_outcome", {
7832
+ entry: freshPrompt !== null ? "submit" : "resume",
7833
+ outcome: "guard_block_continue"
7834
+ });
7796
7835
  continue;
7797
7836
  }
7798
7837
  } else {
@@ -7800,7 +7839,7 @@ ${recipeCtx}`;
7800
7839
  }
7801
7840
  if (guardPassedWrites.length > MAX_BUNDLE_OPS) {
7802
7841
  const cappedError = {
7803
- error: `Compound flows are capped at ${MAX_BUNDLE_OPS} atomic ops per bundle. You attempted ${guardPassedWrites.length}. Split into two sequential bundles (\u2264${MAX_BUNDLE_OPS} ops each) across two confirmation rounds. Tell the user "I'll do this in two steps \u2014 first <ops 1-${MAX_BUNDLE_OPS}>, then after that confirms, <remaining ops>" and emit only the first ${MAX_BUNDLE_OPS} writes for the first bundle.`,
7842
+ error: `Atomic bundles are capped at ${MAX_BUNDLE_OPS} ops in Phase 0. You attempted ${guardPassedWrites.length}. Execute these as ${guardPassedWrites.length} sequential single-write transactions: tell the user "I'll do this in ${guardPassedWrites.length} steps", then emit only the FIRST write. After it lands and the user confirms each step, emit the next.`,
7804
7843
  _gate: "max_bundle_ops"
7805
7844
  };
7806
7845
  for (const write of guardPassedWrites) {
@@ -7820,6 +7859,10 @@ ${recipeCtx}`;
7820
7859
  }
7821
7860
  this.messages.push({ role: "assistant", content: acc.assistantBlocks });
7822
7861
  this.messages.push({ role: "user", content: toolResultBlocks });
7862
+ getTelemetrySink().counter("engine.turn_outcome", {
7863
+ entry: freshPrompt !== null ? "submit" : "resume",
7864
+ outcome: "max_bundle_ops_continue"
7865
+ });
7823
7866
  continue;
7824
7867
  }
7825
7868
  if (guardPassedWrites.length > 0) {
@@ -7827,6 +7870,41 @@ ${recipeCtx}`;
7827
7870
  const turnIndex = this.messages.filter((m) => m.role === "assistant").length;
7828
7871
  this.turnPaused = true;
7829
7872
  if (allBundleable) {
7873
+ if (guardPassedWrites.length === 2) {
7874
+ const producer = guardPassedWrites[0].call.name;
7875
+ const consumer = guardPassedWrites[1].call.name;
7876
+ const check = checkValidPair(producer, consumer);
7877
+ if (!check.ok) {
7878
+ const pairError = {
7879
+ error: `Bundle pair '${check.pair}' is not in the Phase 0 chaining whitelist. Whitelisted pairs: ${[...VALID_PAIRS].join(", ")}. Run these two writes sequentially: tell the user "I'll do this in two steps", emit only the first write, then the second after it lands and confirms.`,
7880
+ _gate: "pair_not_whitelisted"
7881
+ };
7882
+ for (const write of guardPassedWrites) {
7883
+ yield {
7884
+ type: "tool_result",
7885
+ toolName: write.call.name,
7886
+ toolUseId: write.call.id,
7887
+ result: pairError,
7888
+ isError: true
7889
+ };
7890
+ toolResultBlocks.push({
7891
+ type: "tool_result",
7892
+ toolUseId: write.call.id,
7893
+ content: JSON.stringify(pairError),
7894
+ isError: true
7895
+ });
7896
+ }
7897
+ this.turnPaused = false;
7898
+ this.messages.push({ role: "assistant", content: acc.assistantBlocks });
7899
+ this.messages.push({ role: "user", content: toolResultBlocks });
7900
+ getTelemetrySink().counter("engine.turn_outcome", {
7901
+ entry: freshPrompt !== null ? "submit" : "resume",
7902
+ outcome: "pair_not_whitelisted_continue",
7903
+ pair: check.pair
7904
+ });
7905
+ continue;
7906
+ }
7907
+ }
7830
7908
  const completedResults = toolResultBlocks.map((b) => ({
7831
7909
  toolUseId: b.toolUseId,
7832
7910
  content: b.content,
@@ -7842,6 +7920,7 @@ ${recipeCtx}`;
7842
7920
  turnIndex
7843
7921
  });
7844
7922
  yield { type: "pending_action", action: bundleAction };
7923
+ recordTurnOutcome("pending_action_bundle");
7845
7924
  return;
7846
7925
  }
7847
7926
  const pendingWrite = guardPassedWrites[0];
@@ -7889,6 +7968,7 @@ ${recipeCtx}`;
7889
7968
  attemptId
7890
7969
  }
7891
7970
  };
7971
+ recordTurnOutcome("pending_action_single");
7892
7972
  return;
7893
7973
  }
7894
7974
  this.messages.push({ role: "assistant", content: acc.assistantBlocks });
@@ -7900,10 +7980,12 @@ ${recipeCtx}`;
7900
7980
  }
7901
7981
  if (this.costTracker.isOverBudget()) {
7902
7982
  yield { type: "error", error: new Error("Session budget exceeded") };
7983
+ recordTurnOutcome("error_budget");
7903
7984
  return;
7904
7985
  }
7905
7986
  }
7906
7987
  yield { type: "turn_complete", stopReason: "max_turns" };
7988
+ recordTurnOutcome("max_turns");
7907
7989
  }
7908
7990
  // ---------------------------------------------------------------------------
7909
7991
  // Internal
@@ -9374,6 +9456,6 @@ function sanitizeAnthropicMessages(messages) {
9374
9456
  return merged;
9375
9457
  }
9376
9458
 
9377
- 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, WRITE_TOOLS, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, 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, parseRecipe, parseSSE, payApiTool, 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, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
9459
+ 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, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, 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, parseRecipe, parseSSE, payApiTool, 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, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
9378
9460
  //# sourceMappingURL=index.js.map
9379
9461
  //# sourceMappingURL=index.js.map