@t2000/engine 1.13.1 → 1.15.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 +41 -32
- package/dist/index.js +2 -37
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1715,41 +1715,50 @@ declare function bundleShortestTtl(toolUseIds: string[], toolNamesById: Record<s
|
|
|
1715
1715
|
declare const REGENERATABLE_READ_TOOLS: ReadonlySet<string>;
|
|
1716
1716
|
|
|
1717
1717
|
/**
|
|
1718
|
-
* [Phase 0 / SPEC 13
|
|
1719
|
-
*
|
|
1720
|
-
* **History.**
|
|
1721
|
-
* Phase
|
|
1722
|
-
*
|
|
1723
|
-
*
|
|
1724
|
-
*
|
|
1725
|
-
*
|
|
1726
|
-
*
|
|
1727
|
-
*
|
|
1728
|
-
*
|
|
1729
|
-
*
|
|
1730
|
-
*
|
|
1731
|
-
*
|
|
1732
|
-
*
|
|
1733
|
-
*
|
|
1734
|
-
*
|
|
1735
|
-
*
|
|
1736
|
-
*
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1739
|
-
*
|
|
1740
|
-
*
|
|
1741
|
-
*
|
|
1742
|
-
*
|
|
1743
|
-
*
|
|
1744
|
-
*
|
|
1745
|
-
*
|
|
1746
|
-
*
|
|
1718
|
+
* [Phase 0 → Phase 3a / SPEC 13] Maximum number of writes per atomic bundle.
|
|
1719
|
+
*
|
|
1720
|
+
* **History.**
|
|
1721
|
+
* - Pre-Phase-0: 5 (F14-fix-2, 2026-05-03 morning).
|
|
1722
|
+
* - Phase 0 (1.12.0, 2026-05-03 evening): tightened to 2 after the May 3
|
|
1723
|
+
* production review found bundle failures all reduced to chained-asset
|
|
1724
|
+
* gaps — the SDK pre-fetched coins from the wallet and the chained
|
|
1725
|
+
* asset didn't exist yet (e.g. `swap_execute(USDC→USDsui) +
|
|
1726
|
+
* save_deposit(USDsui)` reverted at PREPARE because USDsui wasn't in
|
|
1727
|
+
* the wallet at compose time).
|
|
1728
|
+
* - Phase 1 (1.13.0): cap stayed 2. SPEC 13 Phase 1 added the chained-
|
|
1729
|
+
* coin handoff primitive (`PendingActionStep.inputCoinFromStep` +
|
|
1730
|
+
* `composeTx` orchestration loop) but didn't widen the cap. The
|
|
1731
|
+
* primitive is what makes Phase 2's raise to 3 possible — without it,
|
|
1732
|
+
* every additional step is another wallet-fetch race.
|
|
1733
|
+
* - Phase 2 (1.14.0): cap raised to 3. Composition rule was strict-
|
|
1734
|
+
* adjacency: every (step[i], step[i+1]) pair must be in `VALID_PAIRS`.
|
|
1735
|
+
* Strict adjacency rejected DAG shapes (`swap → save → send` —
|
|
1736
|
+
* last pair `save→send` not in whitelist even though step 3 doesn't
|
|
1737
|
+
* chain from step 2; it pulls a fresh wallet coin).
|
|
1738
|
+
* - **Phase 3a (1.15.0, this version): cap raised to 4. Composition rule
|
|
1739
|
+
* relaxed to DAG-aware: only pairs that actually chain via
|
|
1740
|
+
* `inputCoinFromStep` need whitelist checking. Standalone steps
|
|
1741
|
+
* interleaved between chained steps run wallet-mode independently
|
|
1742
|
+
* inside the same atomic PTB.** This unlocks Demo 1 ("swap 10% to
|
|
1743
|
+
* SUI, save 50% as USDsui, send $100 to Mom" — 4-op DAG with one
|
|
1744
|
+
* chain at step 1→2, three standalone wallet-mode steps).
|
|
1745
|
+
*
|
|
1746
|
+
* **DAG-aware semantics.** Pre-3a: every adjacent pair gates the entire
|
|
1747
|
+
* bundle. Phase 3a+: each (i, i+1) pair contributes IF a chain is wired
|
|
1748
|
+
* (via `shouldChainCoin`). Non-chained pairs are independent — they
|
|
1749
|
+
* each pre-fetch their own coin from the wallet inside the PTB. Atomic
|
|
1750
|
+
* settlement at the PTB level holds either way.
|
|
1751
|
+
*
|
|
1752
|
+
* **Phase 3b (deferred):** `swap_execute → swap_execute` whitelist add
|
|
1753
|
+
* for explicit multi-hop swap chains (rare; flag-gated when shipped).
|
|
1754
|
+
* **Phase 5+:** cap > 4 once production telemetry confirms zero edge-
|
|
1755
|
+
* case revert rate at cap=4.
|
|
1747
1756
|
*
|
|
1748
1757
|
* Hosts importing this constant for system-prompt construction get the
|
|
1749
|
-
* current cap automatically. Bumping the cap
|
|
1750
|
-
*
|
|
1758
|
+
* current cap automatically. Bumping the cap is a one-line change here
|
|
1759
|
+
* that propagates to prompts via the import.
|
|
1751
1760
|
*/
|
|
1752
|
-
declare const MAX_BUNDLE_OPS =
|
|
1761
|
+
declare const MAX_BUNDLE_OPS = 4;
|
|
1753
1762
|
/**
|
|
1754
1763
|
* [Phase 0 / SPEC 13] Whitelisted (producer, consumer) pairs for atomic
|
|
1755
1764
|
* bundling. Every key has the shape `${producer}->${consumer}`. Bundles
|
package/dist/index.js
CHANGED
|
@@ -6737,7 +6737,7 @@ var REGENERATABLE_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
|
6737
6737
|
]);
|
|
6738
6738
|
|
|
6739
6739
|
// src/compose-bundle.ts
|
|
6740
|
-
var MAX_BUNDLE_OPS =
|
|
6740
|
+
var MAX_BUNDLE_OPS = 4;
|
|
6741
6741
|
var VALID_PAIRS = /* @__PURE__ */ new Set([
|
|
6742
6742
|
"swap_execute->send_transfer",
|
|
6743
6743
|
"swap_execute->save_deposit",
|
|
@@ -7885,7 +7885,7 @@ ${recipeCtx}`;
|
|
|
7885
7885
|
}
|
|
7886
7886
|
if (guardPassedWrites.length > MAX_BUNDLE_OPS) {
|
|
7887
7887
|
const cappedError = {
|
|
7888
|
-
error: `Atomic bundles are capped at ${MAX_BUNDLE_OPS} ops
|
|
7888
|
+
error: `Atomic bundles are capped at ${MAX_BUNDLE_OPS} ops. 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.`,
|
|
7889
7889
|
_gate: "max_bundle_ops"
|
|
7890
7890
|
};
|
|
7891
7891
|
for (const write of guardPassedWrites) {
|
|
@@ -7916,41 +7916,6 @@ ${recipeCtx}`;
|
|
|
7916
7916
|
const turnIndex = this.messages.filter((m) => m.role === "assistant").length;
|
|
7917
7917
|
this.turnPaused = true;
|
|
7918
7918
|
if (allBundleable) {
|
|
7919
|
-
if (guardPassedWrites.length === 2) {
|
|
7920
|
-
const producer = guardPassedWrites[0].call.name;
|
|
7921
|
-
const consumer = guardPassedWrites[1].call.name;
|
|
7922
|
-
const check = checkValidPair(producer, consumer);
|
|
7923
|
-
if (!check.ok) {
|
|
7924
|
-
const pairError = {
|
|
7925
|
-
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.`,
|
|
7926
|
-
_gate: "pair_not_whitelisted"
|
|
7927
|
-
};
|
|
7928
|
-
for (const write of guardPassedWrites) {
|
|
7929
|
-
yield {
|
|
7930
|
-
type: "tool_result",
|
|
7931
|
-
toolName: write.call.name,
|
|
7932
|
-
toolUseId: write.call.id,
|
|
7933
|
-
result: pairError,
|
|
7934
|
-
isError: true
|
|
7935
|
-
};
|
|
7936
|
-
toolResultBlocks.push({
|
|
7937
|
-
type: "tool_result",
|
|
7938
|
-
toolUseId: write.call.id,
|
|
7939
|
-
content: JSON.stringify(pairError),
|
|
7940
|
-
isError: true
|
|
7941
|
-
});
|
|
7942
|
-
}
|
|
7943
|
-
this.turnPaused = false;
|
|
7944
|
-
this.messages.push({ role: "assistant", content: acc.assistantBlocks });
|
|
7945
|
-
this.messages.push({ role: "user", content: toolResultBlocks });
|
|
7946
|
-
getTelemetrySink().counter("engine.turn_outcome", {
|
|
7947
|
-
entry: freshPrompt !== null ? "submit" : "resume",
|
|
7948
|
-
outcome: "pair_not_whitelisted_continue",
|
|
7949
|
-
pair: check.pair
|
|
7950
|
-
});
|
|
7951
|
-
continue;
|
|
7952
|
-
}
|
|
7953
|
-
}
|
|
7954
7919
|
const completedResults = toolResultBlocks.map((b) => ({
|
|
7955
7920
|
toolUseId: b.toolUseId,
|
|
7956
7921
|
content: b.content,
|