@t2000/engine 1.6.0 → 1.8.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 +184 -1
- package/dist/index.js +381 -115
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -215,19 +215,19 @@ ${note}`;
|
|
|
215
215
|
|
|
216
216
|
// src/tool-flags.ts
|
|
217
217
|
var TOOL_FLAGS = {
|
|
218
|
-
// Write tools — financial
|
|
219
|
-
save_deposit: { mutating: true, requiresBalance: true },
|
|
220
|
-
withdraw: { mutating: true, affectsHealth: true },
|
|
221
|
-
send_transfer: { mutating: true, requiresBalance: true, irreversible: true },
|
|
222
|
-
swap_execute: { mutating: true, requiresBalance: true },
|
|
223
|
-
borrow: { mutating: true, affectsHealth: true },
|
|
224
|
-
repay_debt: { mutating: true, requiresBalance: true },
|
|
225
|
-
claim_rewards: { mutating: true },
|
|
226
|
-
volo_stake: { mutating: true, requiresBalance: true },
|
|
227
|
-
volo_unstake: { mutating: true },
|
|
228
|
-
// Write tools — pay / services
|
|
218
|
+
// Write tools — financial (bundleable — SPEC 7 Layer 2)
|
|
219
|
+
save_deposit: { mutating: true, requiresBalance: true, bundleable: true },
|
|
220
|
+
withdraw: { mutating: true, affectsHealth: true, bundleable: true },
|
|
221
|
+
send_transfer: { mutating: true, requiresBalance: true, irreversible: true, bundleable: true },
|
|
222
|
+
swap_execute: { mutating: true, requiresBalance: true, bundleable: true },
|
|
223
|
+
borrow: { mutating: true, affectsHealth: true, bundleable: true },
|
|
224
|
+
repay_debt: { mutating: true, requiresBalance: true, bundleable: true },
|
|
225
|
+
claim_rewards: { mutating: true, bundleable: true },
|
|
226
|
+
volo_stake: { mutating: true, requiresBalance: true, bundleable: true },
|
|
227
|
+
volo_unstake: { mutating: true, bundleable: true },
|
|
228
|
+
// Write tools — pay / services (NOT bundleable — see ToolFlags.bundleable JSDoc)
|
|
229
229
|
pay_api: { mutating: true, requiresBalance: true, costAware: true, producesArtifact: true, maxRetries: 1 },
|
|
230
|
-
// Write tools — lightweight (no financial guards)
|
|
230
|
+
// Write tools — lightweight (no financial guards, NOT bundleable — Postgres only)
|
|
231
231
|
save_contact: {},
|
|
232
232
|
// [SIMPLIFICATION DAY 7] Removed flag entries for deleted tools:
|
|
233
233
|
// create_schedule, cancel_schedule (DCA schedules retired)
|
|
@@ -248,6 +248,9 @@ function applyToolFlags(tools) {
|
|
|
248
248
|
function getToolFlags(name) {
|
|
249
249
|
return TOOL_FLAGS[name] ?? {};
|
|
250
250
|
}
|
|
251
|
+
function isBundleableTool(name) {
|
|
252
|
+
return TOOL_FLAGS[name]?.bundleable === true;
|
|
253
|
+
}
|
|
251
254
|
|
|
252
255
|
// src/navi-config.ts
|
|
253
256
|
var NAVI_SERVER_NAME = "navi";
|
|
@@ -5476,6 +5479,51 @@ var CostTracker = class {
|
|
|
5476
5479
|
}
|
|
5477
5480
|
};
|
|
5478
5481
|
|
|
5482
|
+
// src/describe-action.ts
|
|
5483
|
+
function resolveTokenSymbol(nameOrType) {
|
|
5484
|
+
if (!nameOrType.includes("::")) return nameOrType;
|
|
5485
|
+
const parts = nameOrType.split("::");
|
|
5486
|
+
return parts[parts.length - 1];
|
|
5487
|
+
}
|
|
5488
|
+
function describeAction(tool, call) {
|
|
5489
|
+
const input = call.input;
|
|
5490
|
+
switch (tool.name) {
|
|
5491
|
+
case "save_deposit": {
|
|
5492
|
+
return `Save ${input.amount} USDC into lending`;
|
|
5493
|
+
}
|
|
5494
|
+
case "withdraw": {
|
|
5495
|
+
const wAsset = input.asset ?? "";
|
|
5496
|
+
return `Withdraw ${input.amount}${wAsset ? " " + wAsset : ""} from lending`;
|
|
5497
|
+
}
|
|
5498
|
+
case "send_transfer":
|
|
5499
|
+
return `Send $${input.amount} to ${input.to}`;
|
|
5500
|
+
case "borrow":
|
|
5501
|
+
return `Borrow $${input.amount} against collateral`;
|
|
5502
|
+
case "repay_debt":
|
|
5503
|
+
return `Repay $${input.amount} of outstanding debt`;
|
|
5504
|
+
case "claim_rewards":
|
|
5505
|
+
return "Claim all pending protocol rewards";
|
|
5506
|
+
case "pay_api": {
|
|
5507
|
+
const url = String(input.url ?? "");
|
|
5508
|
+
const cost = estimatePayApiCost(url);
|
|
5509
|
+
return `Pay for API call to ${url} (~$${cost})`;
|
|
5510
|
+
}
|
|
5511
|
+
case "swap_execute": {
|
|
5512
|
+
const from = resolveTokenSymbol(String(input.from ?? "?"));
|
|
5513
|
+
const to = resolveTokenSymbol(String(input.to ?? "?"));
|
|
5514
|
+
const amt = input.amount ?? "?";
|
|
5515
|
+
const slippagePct = (input.slippage ?? 0.01) * 100;
|
|
5516
|
+
return `Swap ${amt} ${from} for ${to} (${slippagePct}% max slippage)`;
|
|
5517
|
+
}
|
|
5518
|
+
case "volo_stake":
|
|
5519
|
+
return `Stake ${input.amount} SUI for vSUI`;
|
|
5520
|
+
case "volo_unstake":
|
|
5521
|
+
return `Unstake ${input.amount === "all" ? "all" : input.amount} vSUI`;
|
|
5522
|
+
default:
|
|
5523
|
+
return `Execute ${tool.name}`;
|
|
5524
|
+
}
|
|
5525
|
+
}
|
|
5526
|
+
|
|
5479
5527
|
// src/thinking-budget.ts
|
|
5480
5528
|
var EFFORT_THINKING_BUDGET_CAPS = {
|
|
5481
5529
|
// null = thinking force-disabled (LEAN tier — single-fact reads need
|
|
@@ -6610,6 +6658,98 @@ async function executeTool(tool, call, context) {
|
|
|
6610
6658
|
return { data: result.data, isError: false };
|
|
6611
6659
|
}
|
|
6612
6660
|
|
|
6661
|
+
// src/tool-ttls.ts
|
|
6662
|
+
var TOOL_TTL_MS = {
|
|
6663
|
+
swap_quote: 3e4,
|
|
6664
|
+
rates_info: 9e4,
|
|
6665
|
+
balance_check: 12e4,
|
|
6666
|
+
portfolio_analysis: 12e4,
|
|
6667
|
+
savings_info: 12e4,
|
|
6668
|
+
health_check: 9e4
|
|
6669
|
+
};
|
|
6670
|
+
var DEFAULT_TOOL_TTL_MS = 6e4;
|
|
6671
|
+
function bundleShortestTtl(toolUseIds, toolNamesById) {
|
|
6672
|
+
if (toolUseIds.length === 0) return DEFAULT_TOOL_TTL_MS;
|
|
6673
|
+
let shortest = Number.POSITIVE_INFINITY;
|
|
6674
|
+
for (const id of toolUseIds) {
|
|
6675
|
+
const name = toolNamesById[id];
|
|
6676
|
+
const ttl = (name !== void 0 ? TOOL_TTL_MS[name] : void 0) ?? DEFAULT_TOOL_TTL_MS;
|
|
6677
|
+
if (ttl < shortest) shortest = ttl;
|
|
6678
|
+
}
|
|
6679
|
+
return Number.isFinite(shortest) ? shortest : DEFAULT_TOOL_TTL_MS;
|
|
6680
|
+
}
|
|
6681
|
+
var REGENERATABLE_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
6682
|
+
"swap_quote",
|
|
6683
|
+
"rates_info",
|
|
6684
|
+
"balance_check",
|
|
6685
|
+
"portfolio_analysis",
|
|
6686
|
+
"savings_info",
|
|
6687
|
+
"health_check"
|
|
6688
|
+
]);
|
|
6689
|
+
|
|
6690
|
+
// src/compose-bundle.ts
|
|
6691
|
+
function composeBundleFromToolResults(input) {
|
|
6692
|
+
if (input.pendingWrites.length < 2) {
|
|
6693
|
+
throw new Error(
|
|
6694
|
+
"composeBundleFromToolResults requires \u22652 pending writes; use the legacy single-write path for N=1."
|
|
6695
|
+
);
|
|
6696
|
+
}
|
|
6697
|
+
const steps = input.pendingWrites.map((call) => {
|
|
6698
|
+
const tool = findTool(input.tools, call.name);
|
|
6699
|
+
if (!tool) {
|
|
6700
|
+
throw new Error(`Unknown tool '${call.name}' in bundle composition`);
|
|
6701
|
+
}
|
|
6702
|
+
if (tool.flags?.bundleable !== true) {
|
|
6703
|
+
throw new Error(
|
|
6704
|
+
`Tool '${call.name}' is not bundleable. Set ToolFlags.bundleable=true in tool-flags.ts before including it in a bundle. See SPEC 7 \xA7 "Layer 2 \u2014 Bundleable tools (v1)".`
|
|
6705
|
+
);
|
|
6706
|
+
}
|
|
6707
|
+
const description = describeAction(tool, call);
|
|
6708
|
+
const modifiableFields = getModifiableFields(call.name);
|
|
6709
|
+
return {
|
|
6710
|
+
toolName: call.name,
|
|
6711
|
+
toolUseId: call.id,
|
|
6712
|
+
attemptId: randomUUID(),
|
|
6713
|
+
input: call.input,
|
|
6714
|
+
description,
|
|
6715
|
+
...modifiableFields?.length ? { modifiableFields } : {}
|
|
6716
|
+
};
|
|
6717
|
+
});
|
|
6718
|
+
const regenerateToolUseIds = input.readResults.filter((r) => REGENERATABLE_READ_TOOLS.has(r.toolName)).map((r) => r.toolUseId);
|
|
6719
|
+
const canRegenerate = regenerateToolUseIds.length > 0;
|
|
6720
|
+
let quoteAge;
|
|
6721
|
+
if (regenerateToolUseIds.length > 0) {
|
|
6722
|
+
const stalest = Math.min(
|
|
6723
|
+
...input.readResults.filter((r) => REGENERATABLE_READ_TOOLS.has(r.toolName)).map((r) => r.timestamp)
|
|
6724
|
+
);
|
|
6725
|
+
quoteAge = Math.max(0, Date.now() - stalest);
|
|
6726
|
+
}
|
|
6727
|
+
const allGuardInjections = [];
|
|
6728
|
+
if (input.guardInjectionsByCallId) {
|
|
6729
|
+
for (const call of input.pendingWrites) {
|
|
6730
|
+
const injections = input.guardInjectionsByCallId[call.id];
|
|
6731
|
+
if (injections?.length) allGuardInjections.push(...injections);
|
|
6732
|
+
}
|
|
6733
|
+
}
|
|
6734
|
+
const firstStep = steps[0];
|
|
6735
|
+
const action = {
|
|
6736
|
+
toolName: firstStep.toolName,
|
|
6737
|
+
toolUseId: firstStep.toolUseId,
|
|
6738
|
+
input: firstStep.input,
|
|
6739
|
+
description: firstStep.description,
|
|
6740
|
+
assistantContent: input.assistantContent,
|
|
6741
|
+
completedResults: input.completedResults,
|
|
6742
|
+
...allGuardInjections.length ? { guardInjections: allGuardInjections } : {},
|
|
6743
|
+
turnIndex: input.turnIndex,
|
|
6744
|
+
attemptId: firstStep.attemptId,
|
|
6745
|
+
steps,
|
|
6746
|
+
canRegenerate,
|
|
6747
|
+
...quoteAge !== void 0 ? { quoteAge } : {},
|
|
6748
|
+
...regenerateToolUseIds.length > 0 ? { regenerateInput: { toolUseIds: regenerateToolUseIds } } : {}
|
|
6749
|
+
};
|
|
6750
|
+
return action;
|
|
6751
|
+
}
|
|
6752
|
+
|
|
6613
6753
|
// src/engine.ts
|
|
6614
6754
|
var DEFAULT_MAX_TURNS = 10;
|
|
6615
6755
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
@@ -6760,17 +6900,57 @@ var QueryEngine = class {
|
|
|
6760
6900
|
async *resumeWithToolResult(action, response) {
|
|
6761
6901
|
this.abortController = new AbortController();
|
|
6762
6902
|
const signal = this.abortController.signal;
|
|
6763
|
-
const
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6903
|
+
const isBundle = Array.isArray(action.steps) && action.steps.length > 0;
|
|
6904
|
+
const writeResultBlocks = [];
|
|
6905
|
+
if (isBundle) {
|
|
6906
|
+
const steps = action.steps;
|
|
6907
|
+
const stepResults = response.stepResults ?? [];
|
|
6908
|
+
const resultByToolUseId = new Map(stepResults.map((r) => [r.toolUseId, r]));
|
|
6909
|
+
for (const step of steps) {
|
|
6910
|
+
if (response.approved) {
|
|
6911
|
+
const stepResult = resultByToolUseId.get(step.toolUseId);
|
|
6912
|
+
if (stepResult) {
|
|
6913
|
+
writeResultBlocks.push({
|
|
6914
|
+
type: "tool_result",
|
|
6915
|
+
toolUseId: step.toolUseId,
|
|
6916
|
+
content: JSON.stringify(stepResult.result),
|
|
6917
|
+
isError: stepResult.isError
|
|
6918
|
+
});
|
|
6919
|
+
} else {
|
|
6920
|
+
writeResultBlocks.push({
|
|
6921
|
+
type: "tool_result",
|
|
6922
|
+
toolUseId: step.toolUseId,
|
|
6923
|
+
content: JSON.stringify({
|
|
6924
|
+
error: "Host omitted this step's execution result. Treating as failure \u2014 actual on-chain state is unknown. Re-check wallet via balance_check before re-attempting.",
|
|
6925
|
+
_hostBugMissingStepResult: true
|
|
6926
|
+
}),
|
|
6927
|
+
isError: true
|
|
6928
|
+
});
|
|
6929
|
+
}
|
|
6930
|
+
} else {
|
|
6931
|
+
writeResultBlocks.push({
|
|
6932
|
+
type: "tool_result",
|
|
6933
|
+
toolUseId: step.toolUseId,
|
|
6934
|
+
content: JSON.stringify({ error: "User declined this action" }),
|
|
6935
|
+
isError: true
|
|
6936
|
+
});
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
} else {
|
|
6940
|
+
writeResultBlocks.push(
|
|
6941
|
+
response.approved ? {
|
|
6942
|
+
type: "tool_result",
|
|
6943
|
+
toolUseId: action.toolUseId,
|
|
6944
|
+
content: JSON.stringify(response.executionResult ?? { success: true }),
|
|
6945
|
+
isError: false
|
|
6946
|
+
} : {
|
|
6947
|
+
type: "tool_result",
|
|
6948
|
+
toolUseId: action.toolUseId,
|
|
6949
|
+
content: JSON.stringify({ error: "User declined this action" }),
|
|
6950
|
+
isError: true
|
|
6951
|
+
}
|
|
6952
|
+
);
|
|
6953
|
+
}
|
|
6774
6954
|
if (action.assistantContent?.length) {
|
|
6775
6955
|
this.messages.push({ role: "assistant", content: action.assistantContent });
|
|
6776
6956
|
}
|
|
@@ -6781,16 +6961,47 @@ var QueryEngine = class {
|
|
|
6781
6961
|
content: r.content,
|
|
6782
6962
|
isError: r.isError
|
|
6783
6963
|
})),
|
|
6784
|
-
|
|
6964
|
+
...writeResultBlocks
|
|
6785
6965
|
];
|
|
6786
6966
|
this.messages.push({ role: "user", content: allResults });
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6967
|
+
if (isBundle) {
|
|
6968
|
+
const steps = action.steps;
|
|
6969
|
+
const stepResults = response.stepResults ?? [];
|
|
6970
|
+
const resultByToolUseId = new Map(stepResults.map((r) => [r.toolUseId, r]));
|
|
6971
|
+
for (const step of steps) {
|
|
6972
|
+
const stepResult = resultByToolUseId.get(step.toolUseId);
|
|
6973
|
+
let eventResult;
|
|
6974
|
+
let eventIsError;
|
|
6975
|
+
if (!response.approved) {
|
|
6976
|
+
eventResult = { error: "User declined this action" };
|
|
6977
|
+
eventIsError = true;
|
|
6978
|
+
} else if (stepResult) {
|
|
6979
|
+
eventResult = stepResult.result;
|
|
6980
|
+
eventIsError = stepResult.isError;
|
|
6981
|
+
} else {
|
|
6982
|
+
eventResult = {
|
|
6983
|
+
error: "Host omitted this step's execution result.",
|
|
6984
|
+
_hostBugMissingStepResult: true
|
|
6985
|
+
};
|
|
6986
|
+
eventIsError = true;
|
|
6987
|
+
}
|
|
6988
|
+
yield {
|
|
6989
|
+
type: "tool_result",
|
|
6990
|
+
toolName: step.toolName,
|
|
6991
|
+
toolUseId: step.toolUseId,
|
|
6992
|
+
result: eventResult,
|
|
6993
|
+
isError: eventIsError
|
|
6994
|
+
};
|
|
6995
|
+
}
|
|
6996
|
+
} else {
|
|
6997
|
+
yield {
|
|
6998
|
+
type: "tool_result",
|
|
6999
|
+
toolName: action.toolName,
|
|
7000
|
+
toolUseId: action.toolUseId,
|
|
7001
|
+
result: response.approved ? response.executionResult ?? { success: true } : { error: "User declined this action" },
|
|
7002
|
+
isError: !response.approved
|
|
7003
|
+
};
|
|
7004
|
+
}
|
|
6794
7005
|
if (!response.approved) {
|
|
6795
7006
|
yield { type: "turn_complete", stopReason: "end_turn" };
|
|
6796
7007
|
this.turnReadCache.clear();
|
|
@@ -6817,10 +7028,27 @@ var QueryEngine = class {
|
|
|
6817
7028
|
* the fresh tool results and narrates from them.
|
|
6818
7029
|
*/
|
|
6819
7030
|
async *runPostWriteRefresh(action, response, signal) {
|
|
6820
|
-
const
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
7031
|
+
const isBundle = Array.isArray(action.steps) && action.steps.length > 0;
|
|
7032
|
+
const refreshSet = /* @__PURE__ */ new Set();
|
|
7033
|
+
if (isBundle) {
|
|
7034
|
+
for (const step of action.steps) {
|
|
7035
|
+
const stepRefresh = this.postWriteRefresh?.[step.toolName];
|
|
7036
|
+
if (stepRefresh) for (const t of stepRefresh) refreshSet.add(t);
|
|
7037
|
+
}
|
|
7038
|
+
} else {
|
|
7039
|
+
const singleRefresh = this.postWriteRefresh?.[action.toolName];
|
|
7040
|
+
if (singleRefresh) for (const t of singleRefresh) refreshSet.add(t);
|
|
7041
|
+
}
|
|
7042
|
+
if (refreshSet.size === 0) return;
|
|
7043
|
+
const refreshList = Array.from(refreshSet);
|
|
7044
|
+
const writeFailed = (() => {
|
|
7045
|
+
if (isBundle) {
|
|
7046
|
+
const stepResults = response.stepResults ?? [];
|
|
7047
|
+
return stepResults.some((r) => r.isError);
|
|
7048
|
+
}
|
|
7049
|
+
const exec = response.executionResult;
|
|
7050
|
+
return exec != null && typeof exec === "object" && "success" in exec && exec.success === false;
|
|
7051
|
+
})();
|
|
6824
7052
|
if (writeFailed) return;
|
|
6825
7053
|
const refreshTools = refreshList.map((name) => findTool(this.tools, name)).filter(
|
|
6826
7054
|
(t) => t !== void 0 && t.isReadOnly && t.isConcurrencySafe
|
|
@@ -7067,6 +7295,7 @@ var QueryEngine = class {
|
|
|
7067
7295
|
pendingToolCalls: []
|
|
7068
7296
|
};
|
|
7069
7297
|
const dispatcher = new EarlyToolDispatcher(this.tools, context, this.turnReadCache);
|
|
7298
|
+
const turnReadToolResults = [];
|
|
7070
7299
|
try {
|
|
7071
7300
|
const microcompacted = microcompact(this.messages, this.tools);
|
|
7072
7301
|
this.messages = microcompacted;
|
|
@@ -7217,6 +7446,13 @@ ${recipeCtx}`;
|
|
|
7217
7446
|
};
|
|
7218
7447
|
}
|
|
7219
7448
|
}
|
|
7449
|
+
if (!finalEvent.isError && tool && tool.isReadOnly) {
|
|
7450
|
+
turnReadToolResults.push({
|
|
7451
|
+
toolUseId: finalEvent.toolUseId,
|
|
7452
|
+
toolName: finalEvent.toolName,
|
|
7453
|
+
timestamp: Date.now()
|
|
7454
|
+
});
|
|
7455
|
+
}
|
|
7220
7456
|
earlyResultBlocks.push({
|
|
7221
7457
|
type: "tool_result",
|
|
7222
7458
|
toolUseId: finalEvent.toolUseId,
|
|
@@ -7245,7 +7481,7 @@ ${recipeCtx}`;
|
|
|
7245
7481
|
}
|
|
7246
7482
|
const approved = [];
|
|
7247
7483
|
const toolResultBlocks = [...earlyResultBlocks];
|
|
7248
|
-
|
|
7484
|
+
const pendingWrites = [];
|
|
7249
7485
|
for (const call of acc.pendingToolCalls) {
|
|
7250
7486
|
const tool = findTool(this.tools, call.name);
|
|
7251
7487
|
if (tool && tool.isReadOnly) {
|
|
@@ -7298,8 +7534,7 @@ ${recipeCtx}`;
|
|
|
7298
7534
|
yield { type: "tool_start", toolName: call.name, toolUseId: call.id, input: call.input };
|
|
7299
7535
|
continue;
|
|
7300
7536
|
}
|
|
7301
|
-
|
|
7302
|
-
break;
|
|
7537
|
+
pendingWrites.push({ call, tool });
|
|
7303
7538
|
}
|
|
7304
7539
|
const guardedApproved = [];
|
|
7305
7540
|
if (this.guardConfig) {
|
|
@@ -7396,6 +7631,11 @@ ${recipeCtx}`;
|
|
|
7396
7631
|
result: finalEvent.result,
|
|
7397
7632
|
sourceToolUseId: finalEvent.toolUseId
|
|
7398
7633
|
});
|
|
7634
|
+
turnReadToolResults.push({
|
|
7635
|
+
toolUseId: finalEvent.toolUseId,
|
|
7636
|
+
toolName: finalEvent.toolName,
|
|
7637
|
+
timestamp: Date.now()
|
|
7638
|
+
});
|
|
7399
7639
|
} else {
|
|
7400
7640
|
this.turnReadCache.clear();
|
|
7401
7641
|
}
|
|
@@ -7447,46 +7687,101 @@ ${recipeCtx}`;
|
|
|
7447
7687
|
}
|
|
7448
7688
|
yield toolEvent;
|
|
7449
7689
|
}
|
|
7450
|
-
|
|
7690
|
+
const guardPassedWrites = [];
|
|
7691
|
+
const guardInjectionsByCallId = {};
|
|
7692
|
+
let anyGuardBlocked = false;
|
|
7693
|
+
if (this.guardConfig && pendingWrites.length > 0) {
|
|
7451
7694
|
const convCtx = extractConversationText(this.messages);
|
|
7452
|
-
const
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7695
|
+
for (const write of pendingWrites) {
|
|
7696
|
+
const check = runGuards(
|
|
7697
|
+
write.tool,
|
|
7698
|
+
write.call,
|
|
7699
|
+
this.guardState,
|
|
7700
|
+
this.guardConfig,
|
|
7701
|
+
convCtx,
|
|
7702
|
+
this.onGuardFired,
|
|
7703
|
+
{ contacts: this.contacts, walletAddress: this.walletAddress }
|
|
7704
|
+
);
|
|
7705
|
+
this.guardEvents.push(...check.events);
|
|
7706
|
+
if (check.blocked) {
|
|
7707
|
+
anyGuardBlocked = true;
|
|
7708
|
+
yield {
|
|
7709
|
+
type: "tool_result",
|
|
7710
|
+
toolName: write.call.name,
|
|
7711
|
+
toolUseId: write.call.id,
|
|
7712
|
+
result: { error: check.blockReason, _gate: check.blockGate },
|
|
7713
|
+
isError: true
|
|
7714
|
+
};
|
|
7715
|
+
toolResultBlocks.push({
|
|
7716
|
+
type: "tool_result",
|
|
7717
|
+
toolUseId: write.call.id,
|
|
7718
|
+
content: JSON.stringify({ error: check.blockReason, _gate: check.blockGate }),
|
|
7719
|
+
isError: true
|
|
7720
|
+
});
|
|
7721
|
+
continue;
|
|
7722
|
+
}
|
|
7723
|
+
if (check.injections.length > 0) {
|
|
7724
|
+
guardInjectionsByCallId[write.call.id] = check.injections;
|
|
7725
|
+
write.call._guardInjections = check.injections;
|
|
7726
|
+
}
|
|
7727
|
+
guardPassedWrites.push(write);
|
|
7728
|
+
}
|
|
7729
|
+
if (anyGuardBlocked) {
|
|
7476
7730
|
this.messages.push({ role: "assistant", content: acc.assistantBlocks });
|
|
7477
7731
|
this.messages.push({ role: "user", content: toolResultBlocks });
|
|
7478
7732
|
continue;
|
|
7479
7733
|
}
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
}
|
|
7734
|
+
} else {
|
|
7735
|
+
guardPassedWrites.push(...pendingWrites);
|
|
7483
7736
|
}
|
|
7484
|
-
if (
|
|
7485
|
-
const
|
|
7486
|
-
const modifiableFields = getModifiableFields(pendingWrite.call.name);
|
|
7737
|
+
if (guardPassedWrites.length > 0) {
|
|
7738
|
+
const allBundleable = guardPassedWrites.length >= 2 && guardPassedWrites.every((w) => w.tool.flags?.bundleable === true);
|
|
7487
7739
|
const turnIndex = this.messages.filter((m) => m.role === "assistant").length;
|
|
7488
|
-
const attemptId = randomUUID();
|
|
7489
7740
|
this.turnPaused = true;
|
|
7741
|
+
if (allBundleable) {
|
|
7742
|
+
const completedResults = toolResultBlocks.map((b) => ({
|
|
7743
|
+
toolUseId: b.toolUseId,
|
|
7744
|
+
content: b.content,
|
|
7745
|
+
isError: b.isError ?? false
|
|
7746
|
+
}));
|
|
7747
|
+
const bundleAction = composeBundleFromToolResults({
|
|
7748
|
+
pendingWrites: guardPassedWrites.map((w) => w.call),
|
|
7749
|
+
tools: this.tools,
|
|
7750
|
+
readResults: turnReadToolResults,
|
|
7751
|
+
assistantContent: acc.assistantBlocks,
|
|
7752
|
+
completedResults,
|
|
7753
|
+
guardInjectionsByCallId,
|
|
7754
|
+
turnIndex
|
|
7755
|
+
});
|
|
7756
|
+
yield { type: "pending_action", action: bundleAction };
|
|
7757
|
+
return;
|
|
7758
|
+
}
|
|
7759
|
+
const pendingWrite = guardPassedWrites[0];
|
|
7760
|
+
if (guardPassedWrites.length > 1) {
|
|
7761
|
+
for (let i = 1; i < guardPassedWrites.length; i++) {
|
|
7762
|
+
const dropped = guardPassedWrites[i];
|
|
7763
|
+
const errBody = JSON.stringify({
|
|
7764
|
+
error: "This write was emitted alongside another write that requires a separate confirmation. Re-emit it after the first write resolves.",
|
|
7765
|
+
_droppedDueToMixedBundleability: true
|
|
7766
|
+
});
|
|
7767
|
+
yield {
|
|
7768
|
+
type: "tool_result",
|
|
7769
|
+
toolName: dropped.call.name,
|
|
7770
|
+
toolUseId: dropped.call.id,
|
|
7771
|
+
result: { error: errBody },
|
|
7772
|
+
isError: true
|
|
7773
|
+
};
|
|
7774
|
+
toolResultBlocks.push({
|
|
7775
|
+
type: "tool_result",
|
|
7776
|
+
toolUseId: dropped.call.id,
|
|
7777
|
+
content: errBody,
|
|
7778
|
+
isError: true
|
|
7779
|
+
});
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
const writeGuardInjections = guardInjectionsByCallId[pendingWrite.call.id];
|
|
7783
|
+
const modifiableFields = getModifiableFields(pendingWrite.call.name);
|
|
7784
|
+
const attemptId = randomUUID();
|
|
7490
7785
|
yield {
|
|
7491
7786
|
type: "pending_action",
|
|
7492
7787
|
action: {
|
|
@@ -7697,49 +7992,6 @@ function validateHistory(messages) {
|
|
|
7697
7992
|
}
|
|
7698
7993
|
return merged;
|
|
7699
7994
|
}
|
|
7700
|
-
function resolveTokenSymbol(nameOrType) {
|
|
7701
|
-
if (!nameOrType.includes("::")) return nameOrType;
|
|
7702
|
-
const parts = nameOrType.split("::");
|
|
7703
|
-
return parts[parts.length - 1];
|
|
7704
|
-
}
|
|
7705
|
-
function describeAction(tool, call) {
|
|
7706
|
-
const input = call.input;
|
|
7707
|
-
switch (tool.name) {
|
|
7708
|
-
case "save_deposit": {
|
|
7709
|
-
return `Save ${input.amount} USDC into lending`;
|
|
7710
|
-
}
|
|
7711
|
-
case "withdraw": {
|
|
7712
|
-
const wAsset = input.asset ?? "";
|
|
7713
|
-
return `Withdraw ${input.amount}${wAsset ? " " + wAsset : ""} from lending`;
|
|
7714
|
-
}
|
|
7715
|
-
case "send_transfer":
|
|
7716
|
-
return `Send $${input.amount} to ${input.to}`;
|
|
7717
|
-
case "borrow":
|
|
7718
|
-
return `Borrow $${input.amount} against collateral`;
|
|
7719
|
-
case "repay_debt":
|
|
7720
|
-
return `Repay $${input.amount} of outstanding debt`;
|
|
7721
|
-
case "claim_rewards":
|
|
7722
|
-
return "Claim all pending protocol rewards";
|
|
7723
|
-
case "pay_api": {
|
|
7724
|
-
const url = String(input.url ?? "");
|
|
7725
|
-
const cost = estimatePayApiCost(url);
|
|
7726
|
-
return `Pay for API call to ${url} (~$${cost})`;
|
|
7727
|
-
}
|
|
7728
|
-
case "swap_execute": {
|
|
7729
|
-
const from = resolveTokenSymbol(String(input.from ?? "?"));
|
|
7730
|
-
const to = resolveTokenSymbol(String(input.to ?? "?"));
|
|
7731
|
-
const amt = input.amount ?? "?";
|
|
7732
|
-
const slippagePct = (input.slippage ?? 0.01) * 100;
|
|
7733
|
-
return `Swap ${amt} ${from} for ${to} (${slippagePct}% max slippage)`;
|
|
7734
|
-
}
|
|
7735
|
-
case "volo_stake":
|
|
7736
|
-
return `Stake ${input.amount} SUI for vSUI`;
|
|
7737
|
-
case "volo_unstake":
|
|
7738
|
-
return `Unstake ${input.amount === "all" ? "all" : input.amount} vSUI`;
|
|
7739
|
-
default:
|
|
7740
|
-
return `Execute ${tool.name}`;
|
|
7741
|
-
}
|
|
7742
|
-
}
|
|
7743
7995
|
function flagSuspiciousResult(toolName, result) {
|
|
7744
7996
|
if (!result || typeof result !== "object") return null;
|
|
7745
7997
|
const r = result;
|
|
@@ -7870,7 +8122,8 @@ var StepSchema = z.object({
|
|
|
7870
8122
|
flags: z.record(z.unknown()).optional(),
|
|
7871
8123
|
on_error: OnErrorSchema.optional(),
|
|
7872
8124
|
input_template: z.record(z.string()).optional(),
|
|
7873
|
-
cost_per_unit: z.string().optional()
|
|
8125
|
+
cost_per_unit: z.string().optional(),
|
|
8126
|
+
bundle: z.boolean().optional()
|
|
7874
8127
|
});
|
|
7875
8128
|
var RecipeSchema = z.object({
|
|
7876
8129
|
name: z.string().min(1),
|
|
@@ -7885,6 +8138,19 @@ var RecipeSchema = z.object({
|
|
|
7885
8138
|
return new Set(names).size === names.length;
|
|
7886
8139
|
},
|
|
7887
8140
|
{ message: "Step names must be unique within a recipe" }
|
|
8141
|
+
).refine(
|
|
8142
|
+
(r) => {
|
|
8143
|
+
for (const step of r.steps) {
|
|
8144
|
+
if (step.bundle === true) {
|
|
8145
|
+
if (!step.tool) return false;
|
|
8146
|
+
if (!isBundleableTool(step.tool)) return false;
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
8149
|
+
return true;
|
|
8150
|
+
},
|
|
8151
|
+
{
|
|
8152
|
+
message: "Steps with bundle: true must reference a bundleable confirm-tier write tool. Allowed: save_deposit, withdraw, borrow, repay_debt, send_transfer, swap_execute, claim_rewards, volo_stake, volo_unstake. Forbidden: pay_api, save_contact, any read tool, any auto-tier write."
|
|
8153
|
+
}
|
|
7888
8154
|
);
|
|
7889
8155
|
function loadRecipes(yamlDir) {
|
|
7890
8156
|
const files = readdirSync(yamlDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
@@ -8857,6 +9123,6 @@ function sanitizeAnthropicMessages(messages) {
|
|
|
8857
9123
|
return merged;
|
|
8858
9124
|
}
|
|
8859
9125
|
|
|
8860
|
-
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, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, 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, RecipeRegistry, RetryTracker, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SuinsNotRegisteredError, SuinsRpcError, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, 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, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, 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 };
|
|
9126
|
+
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, 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, 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 };
|
|
8861
9127
|
//# sourceMappingURL=index.js.map
|
|
8862
9128
|
//# sourceMappingURL=index.js.map
|