@t2000/engine 1.12.0 → 1.13.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
@@ -934,6 +934,29 @@ interface PendingActionStep {
934
934
  description: string;
935
935
  /** Optional modifiable fields for THIS step (rare in v1; sourced from `tool-modifiable-fields.ts`). */
936
936
  modifiableFields?: PendingActionModifiableField[];
937
+ /**
938
+ * [SPEC 13 Phase 1] Index of an earlier step whose output coin handle
939
+ * is consumed as THIS step's input coin. When set, the host's
940
+ * `composeTx({ steps })` call must thread `priorOutputs[N]` into this
941
+ * step's appender as `inputCoin` (chain mode), skipping the wallet
942
+ * pre-fetch path. The producer at index `N` MUST be a tool that
943
+ * returns a coin handle (`withdraw`, `borrow`, `swap_execute`,
944
+ * `volo_stake`, `volo_unstake`); the consumer at this index MUST be
945
+ * a tool that accepts an input coin (`save_deposit`, `repay_debt`,
946
+ * `send_transfer`, `swap_execute`, `volo_stake`, `volo_unstake`).
947
+ *
948
+ * Populated by `composeBundleFromToolResults` for whitelisted
949
+ * producer→consumer pairs (see `compose-bundle.ts` `VALID_PAIRS`).
950
+ * Hosts that don't yet honour this field fall back to wallet-mode
951
+ * coin fetching at execute time — which is exactly the pre-Phase-1
952
+ * behaviour and remains correct for the 7 Phase 0 whitelisted pairs
953
+ * because every producer in those pairs leaves its output in the
954
+ * user's wallet via a terminal `tx.transferObjects([coin], sender)`.
955
+ *
956
+ * Pre-condition (validated by `composeTx` at execute time):
957
+ * `inputCoinFromStep < currentStepIndex` (forward-only references).
958
+ */
959
+ inputCoinFromStep?: number;
937
960
  }
938
961
  /**
939
962
  * Serializable description of a write tool that needs user approval.
package/dist/index.js CHANGED
@@ -6746,6 +6746,36 @@ function checkValidPair(producer, consumer) {
6746
6746
  const pair = `${producer}->${consumer}`;
6747
6747
  return VALID_PAIRS.has(pair) ? { ok: true, pair } : { ok: false, pair };
6748
6748
  }
6749
+ function inferProducerOutputAsset(toolName, input) {
6750
+ if (typeof input !== "object" || input === null) return null;
6751
+ const i = input;
6752
+ if (toolName === "swap_execute") {
6753
+ return typeof i.to === "string" ? i.to.toLowerCase() : null;
6754
+ }
6755
+ if (toolName === "withdraw" || toolName === "borrow") {
6756
+ return typeof i.asset === "string" ? i.asset.toLowerCase() : "usdc";
6757
+ }
6758
+ return null;
6759
+ }
6760
+ function inferConsumerInputAsset(toolName, input) {
6761
+ if (typeof input !== "object" || input === null) return null;
6762
+ const i = input;
6763
+ if (toolName === "send_transfer" || toolName === "save_deposit" || toolName === "repay_debt") {
6764
+ return typeof i.asset === "string" ? i.asset.toLowerCase() : "usdc";
6765
+ }
6766
+ if (toolName === "swap_execute") {
6767
+ return typeof i.from === "string" ? i.from.toLowerCase() : null;
6768
+ }
6769
+ return null;
6770
+ }
6771
+ function shouldChainCoin(producer, consumer) {
6772
+ const pair = `${producer.name}->${consumer.name}`;
6773
+ if (!VALID_PAIRS.has(pair)) return false;
6774
+ const out = inferProducerOutputAsset(producer.name, producer.input);
6775
+ const inA = inferConsumerInputAsset(consumer.name, consumer.input);
6776
+ if (!out || !inA) return false;
6777
+ return out === inA;
6778
+ }
6749
6779
  function composeBundleFromToolResults(input) {
6750
6780
  if (input.pendingWrites.length < 2) {
6751
6781
  throw new Error(
@@ -6773,6 +6803,13 @@ function composeBundleFromToolResults(input) {
6773
6803
  ...modifiableFields?.length ? { modifiableFields } : {}
6774
6804
  };
6775
6805
  });
6806
+ for (let i = 1; i < input.pendingWrites.length; i++) {
6807
+ const producer = input.pendingWrites[i - 1];
6808
+ const consumer = input.pendingWrites[i];
6809
+ if (shouldChainCoin(producer, consumer)) {
6810
+ steps[i].inputCoinFromStep = i - 1;
6811
+ }
6812
+ }
6776
6813
  const regenerateToolUseIds = input.readResults.filter((r) => REGENERATABLE_READ_TOOLS.has(r.toolName)).map((r) => r.toolUseId);
6777
6814
  const canRegenerate = regenerateToolUseIds.length > 0;
6778
6815
  let quoteAge;