@t2000/engine 0.40.3 → 0.41.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 +169 -35
- package/dist/index.js +255 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1121,12 +1121,15 @@ async function queryHistoryByDate(rpcUrl, address, targetDate, limit) {
|
|
|
1121
1121
|
}
|
|
1122
1122
|
return results.slice(0, limit);
|
|
1123
1123
|
}
|
|
1124
|
+
var HISTORY_ACTIONS = ["send", "lending", "swap", "transaction"];
|
|
1125
|
+
var DEFAULT_LOOKBACK_DAYS = 30;
|
|
1124
1126
|
var transactionHistoryTool = buildTool({
|
|
1125
1127
|
name: "transaction_history",
|
|
1126
|
-
description: "Retrieve transaction history:
|
|
1128
|
+
description: "Retrieve recent transaction history (last 30 days by default): sends, saves, withdrawals, borrows, repayments, and rewards claims. Pass `date` (YYYY-MM-DD) for a specific day, `action` to filter by category (send/lending/swap), or both.",
|
|
1127
1129
|
inputSchema: z.object({
|
|
1128
1130
|
limit: z.number().int().min(1).max(50).optional(),
|
|
1129
|
-
date: z.string().optional().describe("Specific date to search for transactions (YYYY-MM-DD format). Paginates back to find that day.")
|
|
1131
|
+
date: z.string().optional().describe("Specific date to search for transactions (YYYY-MM-DD format). Paginates back to find that day."),
|
|
1132
|
+
action: z.enum(HISTORY_ACTIONS).optional().describe("Filter by action: send, lending, swap, or transaction.")
|
|
1130
1133
|
}),
|
|
1131
1134
|
jsonSchema: {
|
|
1132
1135
|
type: "object",
|
|
@@ -1138,6 +1141,11 @@ var transactionHistoryTool = buildTool({
|
|
|
1138
1141
|
date: {
|
|
1139
1142
|
type: "string",
|
|
1140
1143
|
description: "Specific date to search for transactions (YYYY-MM-DD format). Paginates back to find that day."
|
|
1144
|
+
},
|
|
1145
|
+
action: {
|
|
1146
|
+
type: "string",
|
|
1147
|
+
enum: [...HISTORY_ACTIONS],
|
|
1148
|
+
description: "Filter results by action category: send, lending, swap, or transaction."
|
|
1141
1149
|
}
|
|
1142
1150
|
}
|
|
1143
1151
|
},
|
|
@@ -1145,29 +1153,55 @@ var transactionHistoryTool = buildTool({
|
|
|
1145
1153
|
maxResultSizeChars: 8e3,
|
|
1146
1154
|
async call(input, context) {
|
|
1147
1155
|
const limit = input.limit ?? 10;
|
|
1156
|
+
const action = input.action;
|
|
1157
|
+
const finalize = (records2) => {
|
|
1158
|
+
let scoped = records2;
|
|
1159
|
+
if (action) scoped = scoped.filter((r) => r.action === action);
|
|
1160
|
+
return scoped.slice(0, limit);
|
|
1161
|
+
};
|
|
1148
1162
|
if (context.agent) {
|
|
1149
1163
|
const agent = requireAgent(context);
|
|
1150
|
-
const records2 = await agent.history({ limit });
|
|
1164
|
+
const records2 = await agent.history({ limit: input.date ? limit : Math.max(limit * 4, 50) });
|
|
1165
|
+
const filtered2 = finalize(records2);
|
|
1151
1166
|
return {
|
|
1152
|
-
data: { transactions:
|
|
1153
|
-
displayText: `${
|
|
1167
|
+
data: { transactions: filtered2, count: filtered2.length, date: input.date ?? null, action: action ?? null },
|
|
1168
|
+
displayText: `${filtered2.length} recent transaction(s)`
|
|
1154
1169
|
};
|
|
1155
1170
|
}
|
|
1156
1171
|
if (!context.walletAddress || !context.suiRpcUrl) {
|
|
1157
1172
|
throw new Error("Transaction history requires a wallet address");
|
|
1158
1173
|
}
|
|
1159
1174
|
if (input.date) {
|
|
1160
|
-
const records2 = await queryHistoryByDate(
|
|
1175
|
+
const records2 = await queryHistoryByDate(
|
|
1176
|
+
context.suiRpcUrl,
|
|
1177
|
+
context.walletAddress,
|
|
1178
|
+
input.date,
|
|
1179
|
+
Math.max(limit * 4, 50)
|
|
1180
|
+
);
|
|
1181
|
+
const filtered2 = finalize(records2);
|
|
1161
1182
|
const dateLabel = new Date(input.date).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
|
|
1162
1183
|
return {
|
|
1163
|
-
data: { transactions:
|
|
1164
|
-
displayText:
|
|
1184
|
+
data: { transactions: filtered2, count: filtered2.length, date: input.date, action: action ?? null },
|
|
1185
|
+
displayText: filtered2.length > 0 ? `${filtered2.length} transaction(s) on ${dateLabel}` : `No transactions found on ${dateLabel}`
|
|
1165
1186
|
};
|
|
1166
1187
|
}
|
|
1167
|
-
const
|
|
1188
|
+
const cutoffMs = Date.now() - DEFAULT_LOOKBACK_DAYS * 864e5;
|
|
1189
|
+
const records = await queryHistoryRpc(
|
|
1190
|
+
context.suiRpcUrl,
|
|
1191
|
+
context.walletAddress,
|
|
1192
|
+
Math.max(limit * 4, 50)
|
|
1193
|
+
);
|
|
1194
|
+
const recent = records.filter((r) => r.timestamp >= cutoffMs);
|
|
1195
|
+
const filtered = finalize(recent);
|
|
1168
1196
|
return {
|
|
1169
|
-
data: {
|
|
1170
|
-
|
|
1197
|
+
data: {
|
|
1198
|
+
transactions: filtered,
|
|
1199
|
+
count: filtered.length,
|
|
1200
|
+
date: null,
|
|
1201
|
+
action: action ?? null,
|
|
1202
|
+
lookbackDays: DEFAULT_LOOKBACK_DAYS
|
|
1203
|
+
},
|
|
1204
|
+
displayText: `${filtered.length} transaction(s) in the last ${DEFAULT_LOOKBACK_DAYS} days`
|
|
1171
1205
|
};
|
|
1172
1206
|
}
|
|
1173
1207
|
});
|
|
@@ -1547,16 +1581,21 @@ function matchesQuery(service, q) {
|
|
|
1547
1581
|
}
|
|
1548
1582
|
var mppServicesTool = buildTool({
|
|
1549
1583
|
name: "mpp_services",
|
|
1550
|
-
description: "Discover available MPP gateway services. Returns service names, descriptions, endpoints with required parameters, and pricing.
|
|
1584
|
+
description: "Discover available MPP gateway services. Returns service names, descriptions, endpoints with required parameters, and pricing. Pass `query` for keyword search or `category` to filter by category. Calling with NO filters returns a category summary (not the full catalog) \u2014 narrow first, then fetch endpoints. Use this BEFORE calling pay_api.",
|
|
1551
1585
|
inputSchema: z.object({
|
|
1552
|
-
query: z.string().optional().describe('Filter by keyword (e.g. "postcard", "translate", "weather").
|
|
1586
|
+
query: z.string().optional().describe('Filter by keyword (e.g. "postcard", "translate", "weather").'),
|
|
1587
|
+
category: z.string().optional().describe('Filter by category exactly (e.g. "weather", "image"). See category summary returned when called without filters.')
|
|
1553
1588
|
}),
|
|
1554
1589
|
jsonSchema: {
|
|
1555
1590
|
type: "object",
|
|
1556
1591
|
properties: {
|
|
1557
1592
|
query: {
|
|
1558
1593
|
type: "string",
|
|
1559
|
-
description: 'Filter by keyword (e.g. "postcard", "translate", "weather").
|
|
1594
|
+
description: 'Filter by keyword (e.g. "postcard", "translate", "weather").'
|
|
1595
|
+
},
|
|
1596
|
+
category: {
|
|
1597
|
+
type: "string",
|
|
1598
|
+
description: 'Filter by category exactly (e.g. "weather", "image").'
|
|
1560
1599
|
}
|
|
1561
1600
|
},
|
|
1562
1601
|
required: []
|
|
@@ -1565,7 +1604,34 @@ var mppServicesTool = buildTool({
|
|
|
1565
1604
|
maxResultSizeChars: 5e3,
|
|
1566
1605
|
async call(input) {
|
|
1567
1606
|
const catalog = await fetchCatalog();
|
|
1568
|
-
|
|
1607
|
+
if (!input.query && !input.category) {
|
|
1608
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1609
|
+
for (const svc of catalog) {
|
|
1610
|
+
for (const cat of svc.categories) {
|
|
1611
|
+
counts.set(cat, (counts.get(cat) ?? 0) + 1);
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
const categories = [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([category, services2]) => ({ category, services: services2 }));
|
|
1615
|
+
return {
|
|
1616
|
+
data: {
|
|
1617
|
+
_refine: {
|
|
1618
|
+
reason: "MPP catalog has many services \u2014 pick a category or supply a query first.",
|
|
1619
|
+
suggestedParams: { category: categories[0]?.category ?? "weather" }
|
|
1620
|
+
},
|
|
1621
|
+
categories,
|
|
1622
|
+
totalServices: catalog.length
|
|
1623
|
+
},
|
|
1624
|
+
displayText: `${catalog.length} services across ${categories.length} categories. Re-call with a category or query.`
|
|
1625
|
+
};
|
|
1626
|
+
}
|
|
1627
|
+
let filtered = catalog;
|
|
1628
|
+
if (input.category) {
|
|
1629
|
+
const cat = input.category.toLowerCase();
|
|
1630
|
+
filtered = filtered.filter((s) => s.categories.some((c) => c.toLowerCase() === cat));
|
|
1631
|
+
}
|
|
1632
|
+
if (input.query) {
|
|
1633
|
+
filtered = filtered.filter((s) => matchesQuery(s, input.query));
|
|
1634
|
+
}
|
|
1569
1635
|
const services = filtered.map((s) => ({
|
|
1570
1636
|
id: s.id,
|
|
1571
1637
|
name: s.name,
|
|
@@ -1578,7 +1644,11 @@ var mppServicesTool = buildTool({
|
|
|
1578
1644
|
price: `$${e.price}`
|
|
1579
1645
|
}))
|
|
1580
1646
|
}));
|
|
1581
|
-
const
|
|
1647
|
+
const filterDesc = [
|
|
1648
|
+
input.query ? `query "${input.query}"` : null,
|
|
1649
|
+
input.category ? `category "${input.category}"` : null
|
|
1650
|
+
].filter(Boolean).join(" + ");
|
|
1651
|
+
const summary = `Found ${services.length} service(s) matching ${filterDesc}`;
|
|
1582
1652
|
return {
|
|
1583
1653
|
data: { services, total: services.length },
|
|
1584
1654
|
displayText: summary
|
|
@@ -2830,6 +2900,10 @@ async function cachedFetch(url) {
|
|
|
2830
2900
|
apiCache.set(url, { data, ts: Date.now() });
|
|
2831
2901
|
return data;
|
|
2832
2902
|
}
|
|
2903
|
+
async function fetchDefillamaYieldPools() {
|
|
2904
|
+
const data = await cachedFetch(`${YIELDS_API2}/pools`);
|
|
2905
|
+
return data.data ?? [];
|
|
2906
|
+
}
|
|
2833
2907
|
function fmtToolTvl(tvl) {
|
|
2834
2908
|
if (tvl >= 1e9) return `$${(tvl / 1e9).toFixed(1)}B`;
|
|
2835
2909
|
if (tvl >= 1e6) return `$${(tvl / 1e6).toFixed(1)}M`;
|
|
@@ -2858,8 +2932,25 @@ var defillamaYieldPoolsTool = buildTool({
|
|
|
2858
2932
|
isReadOnly: true,
|
|
2859
2933
|
maxResultSizeChars: 6e3,
|
|
2860
2934
|
async call(input) {
|
|
2861
|
-
|
|
2862
|
-
|
|
2935
|
+
if (!input.chain && !input.project) {
|
|
2936
|
+
const all = await fetchDefillamaYieldPools();
|
|
2937
|
+
const chainCounts = /* @__PURE__ */ new Map();
|
|
2938
|
+
for (const p of all) {
|
|
2939
|
+
chainCounts.set(p.chain, (chainCounts.get(p.chain) ?? 0) + 1);
|
|
2940
|
+
}
|
|
2941
|
+
const topChains = [...chainCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([chain, count]) => ({ chain, pools: count }));
|
|
2942
|
+
return {
|
|
2943
|
+
data: {
|
|
2944
|
+
_refine: {
|
|
2945
|
+
reason: "Cross-chain yield search is too broad; pick a chain.",
|
|
2946
|
+
suggestedParams: { chain: "Sui" },
|
|
2947
|
+
availableChains: topChains
|
|
2948
|
+
}
|
|
2949
|
+
},
|
|
2950
|
+
displayText: "Yield query needs a chain filter. Common chains: " + topChains.map((c) => c.chain).join(", ")
|
|
2951
|
+
};
|
|
2952
|
+
}
|
|
2953
|
+
let pools = await fetchDefillamaYieldPools();
|
|
2863
2954
|
if (input.chain) {
|
|
2864
2955
|
const chain = input.chain.toLowerCase();
|
|
2865
2956
|
pools = pools.filter((p) => p.chain.toLowerCase() === chain);
|
|
@@ -3149,8 +3240,42 @@ function getDefaultTools() {
|
|
|
3149
3240
|
return applyToolFlags([...READ_TOOLS, ...WRITE_TOOLS]);
|
|
3150
3241
|
}
|
|
3151
3242
|
|
|
3243
|
+
// src/tools/tool-modifiable-fields.ts
|
|
3244
|
+
var TOOL_MODIFIABLE_FIELDS = {
|
|
3245
|
+
save_deposit: [
|
|
3246
|
+
{ name: "amount", kind: "amount", asset: "USDC" }
|
|
3247
|
+
],
|
|
3248
|
+
withdraw: [
|
|
3249
|
+
{ name: "amount", kind: "amount", asset: "USDC" }
|
|
3250
|
+
],
|
|
3251
|
+
send_transfer: [
|
|
3252
|
+
// `amount` first so the UI surfaces it prominently; the recipient
|
|
3253
|
+
// address field is also editable in case the user typed the wrong one.
|
|
3254
|
+
{ name: "amount", kind: "amount" },
|
|
3255
|
+
{ name: "to", kind: "address" }
|
|
3256
|
+
],
|
|
3257
|
+
swap_execute: [
|
|
3258
|
+
{ name: "amount", kind: "amount" }
|
|
3259
|
+
],
|
|
3260
|
+
borrow: [
|
|
3261
|
+
{ name: "amount", kind: "amount", asset: "USDC" }
|
|
3262
|
+
],
|
|
3263
|
+
repay_debt: [
|
|
3264
|
+
{ name: "amount", kind: "amount", asset: "USDC" }
|
|
3265
|
+
],
|
|
3266
|
+
volo_stake: [
|
|
3267
|
+
{ name: "amount", kind: "amount", asset: "SUI" }
|
|
3268
|
+
],
|
|
3269
|
+
volo_unstake: [
|
|
3270
|
+
{ name: "amount", kind: "amount", asset: "vSUI" }
|
|
3271
|
+
]
|
|
3272
|
+
};
|
|
3273
|
+
function getModifiableFields(toolName) {
|
|
3274
|
+
return TOOL_MODIFIABLE_FIELDS[toolName];
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3152
3277
|
// src/prompt.ts
|
|
3153
|
-
var DEFAULT_SYSTEM_PROMPT = `You are Audric \u2014 a financial agent on Sui. Audric is exactly
|
|
3278
|
+
var DEFAULT_SYSTEM_PROMPT = `You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 40 tools, Reasoning Engine with 9 guards and 7 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say "coming soon" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.
|
|
3154
3279
|
|
|
3155
3280
|
## Response rules
|
|
3156
3281
|
- 1-2 sentences max. No bullet lists unless asked. No preambles.
|
|
@@ -3248,6 +3373,11 @@ var CostTracker = class {
|
|
|
3248
3373
|
};
|
|
3249
3374
|
|
|
3250
3375
|
// src/guards.ts
|
|
3376
|
+
function guardVerdictToAction(verdict) {
|
|
3377
|
+
if (verdict === "pass" || verdict === "hint") return "allow";
|
|
3378
|
+
if (verdict === "warn") return "warn";
|
|
3379
|
+
return "block";
|
|
3380
|
+
}
|
|
3251
3381
|
var DEFAULT_GUARD_CONFIG = {
|
|
3252
3382
|
balanceValidation: true,
|
|
3253
3383
|
healthFactor: { warnBelow: 2, blockBelow: 1.5 },
|
|
@@ -3464,9 +3594,22 @@ function createGuardRunnerState() {
|
|
|
3464
3594
|
lastHealthFactor: null
|
|
3465
3595
|
};
|
|
3466
3596
|
}
|
|
3467
|
-
function runGuards(tool, call, state, config, conversationContext) {
|
|
3597
|
+
function runGuards(tool, call, state, config, conversationContext, onGuardFired) {
|
|
3468
3598
|
const results = [];
|
|
3469
3599
|
const now = Date.now();
|
|
3600
|
+
const fire = (verdict, tier, gate, hadInjection) => {
|
|
3601
|
+
if (!onGuardFired) return;
|
|
3602
|
+
try {
|
|
3603
|
+
onGuardFired({
|
|
3604
|
+
name: gate,
|
|
3605
|
+
tier,
|
|
3606
|
+
action: guardVerdictToAction(verdict),
|
|
3607
|
+
injectionAdded: hadInjection
|
|
3608
|
+
});
|
|
3609
|
+
} catch (err) {
|
|
3610
|
+
console.warn("[guards] onGuardFired threw (ignored):", err);
|
|
3611
|
+
}
|
|
3612
|
+
};
|
|
3470
3613
|
if (config.inputValidation !== false && tool.preflight) {
|
|
3471
3614
|
const check = tool.preflight(call.input);
|
|
3472
3615
|
if (!check.valid) {
|
|
@@ -3479,6 +3622,7 @@ function runGuards(tool, call, state, config, conversationContext) {
|
|
|
3479
3622
|
tier: "safety",
|
|
3480
3623
|
message: check.error
|
|
3481
3624
|
};
|
|
3625
|
+
fire("block", "safety", "input_validation", false);
|
|
3482
3626
|
return {
|
|
3483
3627
|
blocked: true,
|
|
3484
3628
|
blockReason: check.error,
|
|
@@ -3520,6 +3664,10 @@ function runGuards(tool, call, state, config, conversationContext) {
|
|
|
3520
3664
|
}));
|
|
3521
3665
|
const block = results.find((r) => r.verdict === "block");
|
|
3522
3666
|
if (block) {
|
|
3667
|
+
for (const r of results) {
|
|
3668
|
+
if (r.verdict === "pass") continue;
|
|
3669
|
+
fire(r.verdict, r.tier, r.gate, false);
|
|
3670
|
+
}
|
|
3523
3671
|
return {
|
|
3524
3672
|
blocked: true,
|
|
3525
3673
|
blockReason: block.message ?? `Blocked by ${block.gate}`,
|
|
@@ -3532,6 +3680,10 @@ function runGuards(tool, call, state, config, conversationContext) {
|
|
|
3532
3680
|
_gate: r.gate,
|
|
3533
3681
|
...r.verdict === "hint" ? { _hint: r.message } : { _warning: r.message }
|
|
3534
3682
|
}));
|
|
3683
|
+
for (const r of results) {
|
|
3684
|
+
if (r.verdict === "pass") continue;
|
|
3685
|
+
fire(r.verdict, r.tier, r.gate, r.verdict === "hint" || r.verdict === "warn");
|
|
3686
|
+
}
|
|
3535
3687
|
return { blocked: false, injections, events };
|
|
3536
3688
|
}
|
|
3537
3689
|
function updateGuardStateAfterToolResult(toolName, tool, input, result, isError, state) {
|
|
@@ -3576,6 +3728,7 @@ function microcompact(messages) {
|
|
|
3576
3728
|
const seen = /* @__PURE__ */ new Map();
|
|
3577
3729
|
let toolUseIndex = 0;
|
|
3578
3730
|
const toolUseInputs = /* @__PURE__ */ new Map();
|
|
3731
|
+
const dedupedToolUseIds = /* @__PURE__ */ new Set();
|
|
3579
3732
|
for (const msg of messages) {
|
|
3580
3733
|
for (const block of msg.content) {
|
|
3581
3734
|
if (block.type === "tool_use") {
|
|
@@ -3583,7 +3736,7 @@ function microcompact(messages) {
|
|
|
3583
3736
|
}
|
|
3584
3737
|
}
|
|
3585
3738
|
}
|
|
3586
|
-
|
|
3739
|
+
const out = messages.map((msg) => {
|
|
3587
3740
|
if (msg.role !== "user") return { role: msg.role, content: [...msg.content] };
|
|
3588
3741
|
const hasToolResults = msg.content.some((b) => b.type === "tool_result");
|
|
3589
3742
|
if (!hasToolResults) return { role: msg.role, content: [...msg.content] };
|
|
@@ -3594,6 +3747,7 @@ function microcompact(messages) {
|
|
|
3594
3747
|
toolUseIndex++;
|
|
3595
3748
|
const prior = seen.get(key);
|
|
3596
3749
|
if (prior && !block.isError) {
|
|
3750
|
+
dedupedToolUseIds.add(block.toolUseId);
|
|
3597
3751
|
return {
|
|
3598
3752
|
...block,
|
|
3599
3753
|
content: `[Same result as call #${prior.turnIndex} \u2014 ${key.split(":")[0]} with identical inputs. Result unchanged.]`
|
|
@@ -3606,6 +3760,13 @@ function microcompact(messages) {
|
|
|
3606
3760
|
});
|
|
3607
3761
|
return { role: msg.role, content: newContent };
|
|
3608
3762
|
});
|
|
3763
|
+
Object.defineProperty(out, "dedupedToolUseIds", {
|
|
3764
|
+
value: dedupedToolUseIds,
|
|
3765
|
+
enumerable: false,
|
|
3766
|
+
writable: false,
|
|
3767
|
+
configurable: false
|
|
3768
|
+
});
|
|
3769
|
+
return out;
|
|
3609
3770
|
}
|
|
3610
3771
|
function stableStringify(value) {
|
|
3611
3772
|
if (value === null || value === void 0) return "";
|
|
@@ -3845,13 +4006,18 @@ var PERMISSION_PRESETS = {
|
|
|
3845
4006
|
]
|
|
3846
4007
|
}
|
|
3847
4008
|
};
|
|
3848
|
-
function resolvePermissionTier(operation, amountUsd, config) {
|
|
4009
|
+
function resolvePermissionTier(operation, amountUsd, config, sessionSpendUsd) {
|
|
3849
4010
|
const rule = config.rules.find((r) => r.operation === operation);
|
|
3850
4011
|
const autoBelow = rule?.autoBelow ?? config.globalAutoBelow;
|
|
3851
4012
|
const confirmBetween = rule?.confirmBetween ?? 1e3;
|
|
3852
|
-
|
|
3853
|
-
if (amountUsd <
|
|
3854
|
-
|
|
4013
|
+
let tier;
|
|
4014
|
+
if (amountUsd < autoBelow) tier = "auto";
|
|
4015
|
+
else if (amountUsd < confirmBetween) tier = "confirm";
|
|
4016
|
+
else tier = "explicit";
|
|
4017
|
+
if (tier === "auto" && typeof sessionSpendUsd === "number" && sessionSpendUsd + amountUsd > config.autonomousDailyLimit) {
|
|
4018
|
+
return "confirm";
|
|
4019
|
+
}
|
|
4020
|
+
return tier;
|
|
3855
4021
|
}
|
|
3856
4022
|
var TOOL_TO_OPERATION = {
|
|
3857
4023
|
save_deposit: "save",
|
|
@@ -3945,7 +4111,8 @@ var EarlyToolDispatcher = class {
|
|
|
3945
4111
|
toolName: entry.call.name,
|
|
3946
4112
|
toolUseId: entry.call.id,
|
|
3947
4113
|
result: budgeted,
|
|
3948
|
-
isError: result.isError
|
|
4114
|
+
isError: result.isError,
|
|
4115
|
+
wasEarlyDispatched: true
|
|
3949
4116
|
};
|
|
3950
4117
|
} catch (err) {
|
|
3951
4118
|
yield {
|
|
@@ -3953,7 +4120,8 @@ var EarlyToolDispatcher = class {
|
|
|
3953
4120
|
toolName: entry.call.name,
|
|
3954
4121
|
toolUseId: entry.call.id,
|
|
3955
4122
|
result: { error: err instanceof Error ? err.message : "Tool execution failed" },
|
|
3956
|
-
isError: true
|
|
4123
|
+
isError: true,
|
|
4124
|
+
wasEarlyDispatched: true
|
|
3957
4125
|
};
|
|
3958
4126
|
}
|
|
3959
4127
|
}
|
|
@@ -4005,6 +4173,10 @@ var QueryEngine = class {
|
|
|
4005
4173
|
contextSummarizer;
|
|
4006
4174
|
priceCache;
|
|
4007
4175
|
permissionConfig;
|
|
4176
|
+
// [v1.4] Session-scoped autonomous spend tracking.
|
|
4177
|
+
sessionSpendUsd;
|
|
4178
|
+
onAutoExecuted;
|
|
4179
|
+
onGuardFired;
|
|
4008
4180
|
matchedRecipe = null;
|
|
4009
4181
|
messages = [];
|
|
4010
4182
|
abortController = null;
|
|
@@ -4034,6 +4206,9 @@ var QueryEngine = class {
|
|
|
4034
4206
|
this.contextSummarizer = config.contextSummarizer;
|
|
4035
4207
|
this.priceCache = config.priceCache;
|
|
4036
4208
|
this.permissionConfig = config.permissionConfig;
|
|
4209
|
+
this.sessionSpendUsd = config.sessionSpendUsd;
|
|
4210
|
+
this.onAutoExecuted = config.onAutoExecuted;
|
|
4211
|
+
this.onGuardFired = config.onGuardFired;
|
|
4037
4212
|
this.tools = config.tools ?? (config.agent ? getDefaultTools() : []);
|
|
4038
4213
|
}
|
|
4039
4214
|
/**
|
|
@@ -4155,7 +4330,8 @@ var QueryEngine = class {
|
|
|
4155
4330
|
env: this.env,
|
|
4156
4331
|
signal,
|
|
4157
4332
|
priceCache: this.priceCache,
|
|
4158
|
-
permissionConfig: this.permissionConfig
|
|
4333
|
+
permissionConfig: this.permissionConfig,
|
|
4334
|
+
sessionSpendUsd: this.sessionSpendUsd
|
|
4159
4335
|
};
|
|
4160
4336
|
let turns = 0;
|
|
4161
4337
|
let hasRetriedWithCleanHistory = false;
|
|
@@ -4174,13 +4350,25 @@ var QueryEngine = class {
|
|
|
4174
4350
|
};
|
|
4175
4351
|
const dispatcher = new EarlyToolDispatcher(this.tools, context);
|
|
4176
4352
|
try {
|
|
4177
|
-
|
|
4353
|
+
const microcompacted = microcompact(this.messages);
|
|
4354
|
+
this.messages = microcompacted;
|
|
4355
|
+
for (const dedupedId of microcompacted.dedupedToolUseIds) {
|
|
4356
|
+
yield {
|
|
4357
|
+
type: "tool_result",
|
|
4358
|
+
toolName: "__deduped__",
|
|
4359
|
+
toolUseId: dedupedId,
|
|
4360
|
+
result: null,
|
|
4361
|
+
isError: false,
|
|
4362
|
+
resultDeduped: true
|
|
4363
|
+
};
|
|
4364
|
+
}
|
|
4178
4365
|
if (this.contextBudget.shouldCompact()) {
|
|
4179
4366
|
this.messages = await compactMessages(this.messages, {
|
|
4180
4367
|
maxTokens: 1e5,
|
|
4181
4368
|
keepRecentCount: 8,
|
|
4182
4369
|
summarizer: this.contextSummarizer
|
|
4183
4370
|
});
|
|
4371
|
+
yield { type: "compaction" };
|
|
4184
4372
|
}
|
|
4185
4373
|
this.messages = validateHistory(this.messages);
|
|
4186
4374
|
if (process.env.NODE_ENV !== "test") {
|
|
@@ -4340,7 +4528,12 @@ ${recipeCtx}`;
|
|
|
4340
4528
|
const operation = toolNameToOperation(call.name);
|
|
4341
4529
|
if (operation) {
|
|
4342
4530
|
const usdValue = resolveUsdValue(call.name, call.input, context.priceCache);
|
|
4343
|
-
const tier = resolvePermissionTier(
|
|
4531
|
+
const tier = resolvePermissionTier(
|
|
4532
|
+
operation,
|
|
4533
|
+
usdValue,
|
|
4534
|
+
context.permissionConfig,
|
|
4535
|
+
context.sessionSpendUsd
|
|
4536
|
+
);
|
|
4344
4537
|
return tier !== "auto";
|
|
4345
4538
|
}
|
|
4346
4539
|
}
|
|
@@ -4363,7 +4556,14 @@ ${recipeCtx}`;
|
|
|
4363
4556
|
guardedApproved.push(call);
|
|
4364
4557
|
continue;
|
|
4365
4558
|
}
|
|
4366
|
-
const check = runGuards(
|
|
4559
|
+
const check = runGuards(
|
|
4560
|
+
tool,
|
|
4561
|
+
call,
|
|
4562
|
+
this.guardState,
|
|
4563
|
+
this.guardConfig,
|
|
4564
|
+
convCtx,
|
|
4565
|
+
this.onGuardFired
|
|
4566
|
+
);
|
|
4367
4567
|
this.guardEvents.push(...check.events);
|
|
4368
4568
|
if (check.blocked) {
|
|
4369
4569
|
yield {
|
|
@@ -4445,6 +4645,22 @@ ${recipeCtx}`;
|
|
|
4445
4645
|
toolUseId: finalEvent.toolUseId
|
|
4446
4646
|
};
|
|
4447
4647
|
}
|
|
4648
|
+
if (tool && !tool.isReadOnly && this.onAutoExecuted && this.permissionConfig && this.priceCache) {
|
|
4649
|
+
const operation = toolNameToOperation(toolEvent.toolName);
|
|
4650
|
+
if (operation && originalCall) {
|
|
4651
|
+
const usdValue = resolveUsdValue(
|
|
4652
|
+
toolEvent.toolName,
|
|
4653
|
+
originalCall.input,
|
|
4654
|
+
this.priceCache
|
|
4655
|
+
);
|
|
4656
|
+
Promise.resolve().then(() => this.onAutoExecuted({
|
|
4657
|
+
toolName: toolEvent.toolName,
|
|
4658
|
+
usdValue
|
|
4659
|
+
})).catch((err) => {
|
|
4660
|
+
console.warn("[engine] onAutoExecuted callback failed:", err);
|
|
4661
|
+
});
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4448
4664
|
}
|
|
4449
4665
|
toolResultBlocks.push({
|
|
4450
4666
|
type: "tool_result",
|
|
@@ -4463,7 +4679,8 @@ ${recipeCtx}`;
|
|
|
4463
4679
|
pendingWrite.call,
|
|
4464
4680
|
this.guardState,
|
|
4465
4681
|
this.guardConfig,
|
|
4466
|
-
convCtx
|
|
4682
|
+
convCtx,
|
|
4683
|
+
this.onGuardFired
|
|
4467
4684
|
);
|
|
4468
4685
|
this.guardEvents.push(...check.events);
|
|
4469
4686
|
if (check.blocked) {
|
|
@@ -4490,6 +4707,8 @@ ${recipeCtx}`;
|
|
|
4490
4707
|
}
|
|
4491
4708
|
if (pendingWrite) {
|
|
4492
4709
|
const writeGuardInjections = pendingWrite.call._guardInjections;
|
|
4710
|
+
const modifiableFields = getModifiableFields(pendingWrite.call.name);
|
|
4711
|
+
const turnIndex = this.messages.filter((m) => m.role === "assistant").length;
|
|
4493
4712
|
yield {
|
|
4494
4713
|
type: "pending_action",
|
|
4495
4714
|
action: {
|
|
@@ -4503,7 +4722,9 @@ ${recipeCtx}`;
|
|
|
4503
4722
|
content: b.content,
|
|
4504
4723
|
isError: b.isError ?? false
|
|
4505
4724
|
})),
|
|
4506
|
-
...writeGuardInjections?.length ? { guardInjections: writeGuardInjections } : {}
|
|
4725
|
+
...writeGuardInjections?.length ? { guardInjections: writeGuardInjections } : {},
|
|
4726
|
+
...modifiableFields?.length ? { modifiableFields } : {},
|
|
4727
|
+
turnIndex
|
|
4507
4728
|
}
|
|
4508
4729
|
};
|
|
4509
4730
|
return;
|
|
@@ -5670,6 +5891,6 @@ function sanitizeAnthropicMessages(messages) {
|
|
|
5670
5891
|
return merged;
|
|
5671
5892
|
}
|
|
5672
5893
|
|
|
5673
|
-
export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPriceCache, compactMessages, createGuardRunnerState, defillamaChainTvlTool, defillamaPriceChangeTool, defillamaProtocolFeesTool, defillamaProtocolInfoTool, defillamaSuiProtocolsTool, defillamaTokenPricesTool, defillamaYieldPoolsTool, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
|
|
5894
|
+
export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPriceCache, compactMessages, createGuardRunnerState, defillamaChainTvlTool, defillamaPriceChangeTool, defillamaProtocolFeesTool, defillamaProtocolInfoTool, defillamaSuiProtocolsTool, defillamaTokenPricesTool, defillamaYieldPoolsTool, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
|
|
5674
5895
|
//# sourceMappingURL=index.js.map
|
|
5675
5896
|
//# sourceMappingURL=index.js.map
|