@t2000/engine 0.30.0 → 0.31.1
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 +1 -10
- package/dist/index.js +220 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -832,19 +832,10 @@ declare const healthCheckTool: Tool<{}, {
|
|
|
832
832
|
|
|
833
833
|
declare const ratesInfoTool: Tool<{}, _t2000_sdk.RatesResult>;
|
|
834
834
|
|
|
835
|
-
interface TxRecord {
|
|
836
|
-
digest: string;
|
|
837
|
-
action: string;
|
|
838
|
-
amount?: number;
|
|
839
|
-
asset?: string;
|
|
840
|
-
recipient?: string;
|
|
841
|
-
timestamp: number;
|
|
842
|
-
gasCost?: number;
|
|
843
|
-
}
|
|
844
835
|
declare const transactionHistoryTool: Tool<{
|
|
845
836
|
limit?: number | undefined;
|
|
846
837
|
}, {
|
|
847
|
-
transactions:
|
|
838
|
+
transactions: _t2000_sdk.TransactionRecord[];
|
|
848
839
|
count: number;
|
|
849
840
|
}>;
|
|
850
841
|
|
package/dist/index.js
CHANGED
|
@@ -980,13 +980,15 @@ function parseRpcTx(tx, address) {
|
|
|
980
980
|
const recipientChange = inflows.find((c) => c.coinType === coinType);
|
|
981
981
|
recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? void 0 : void 0;
|
|
982
982
|
}
|
|
983
|
+
const timestampMs = Number(tx.timestampMs ?? 0);
|
|
983
984
|
return {
|
|
984
985
|
digest: tx.digest,
|
|
985
986
|
action: classifyAction(moveCallTargets, commandTypes),
|
|
986
987
|
amount,
|
|
987
988
|
asset,
|
|
988
989
|
recipient,
|
|
989
|
-
timestamp:
|
|
990
|
+
timestamp: timestampMs,
|
|
991
|
+
date: timestampMs > 0 ? new Date(timestampMs).toISOString() : void 0,
|
|
990
992
|
gasCost
|
|
991
993
|
};
|
|
992
994
|
}
|
|
@@ -2645,6 +2647,7 @@ Always prefer the canvas for visualisation requests. After rendering, offer to e
|
|
|
2645
2647
|
};
|
|
2646
2648
|
}
|
|
2647
2649
|
if (template === "health_simulator") {
|
|
2650
|
+
const roundedDebt = totalBorrows >= 1 ? Math.round(totalBorrows) : totalBorrows > 0 ? parseFloat(totalBorrows.toFixed(4)) : 0;
|
|
2648
2651
|
return {
|
|
2649
2652
|
data: {
|
|
2650
2653
|
__canvas: true,
|
|
@@ -2653,7 +2656,7 @@ Always prefer the canvas for visualisation requests. After rendering, offer to e
|
|
|
2653
2656
|
templateData: {
|
|
2654
2657
|
available: true,
|
|
2655
2658
|
initialCollateral: totalSavings > 0 ? Math.round(totalSavings) : 1500,
|
|
2656
|
-
initialDebt:
|
|
2659
|
+
initialDebt: roundedDebt > 0 ? roundedDebt : totalSavings > 0 ? 0 : 500,
|
|
2657
2660
|
currentHf: healthFactor
|
|
2658
2661
|
}
|
|
2659
2662
|
},
|
|
@@ -2821,6 +2824,216 @@ var activitySummaryTool = buildTool({
|
|
|
2821
2824
|
}
|
|
2822
2825
|
}
|
|
2823
2826
|
});
|
|
2827
|
+
function getApiConfig(context) {
|
|
2828
|
+
const apiUrl = context.env?.ALLOWANCE_API_URL;
|
|
2829
|
+
const internalKey = context.env?.AUDRIC_INTERNAL_KEY;
|
|
2830
|
+
const address = context.walletAddress;
|
|
2831
|
+
return { apiUrl, internalKey, address };
|
|
2832
|
+
}
|
|
2833
|
+
function parseCronFromDescription(input) {
|
|
2834
|
+
const lower = input.toLowerCase().trim();
|
|
2835
|
+
if (/^\d+\s/.test(lower) || lower.startsWith("*")) return lower;
|
|
2836
|
+
if (/every\s*day|daily/.test(lower)) {
|
|
2837
|
+
const hourMatch = lower.match(/at\s*(\d{1,2})\s*(am|pm)?/i);
|
|
2838
|
+
let hour = 9;
|
|
2839
|
+
if (hourMatch) {
|
|
2840
|
+
hour = parseInt(hourMatch[1], 10);
|
|
2841
|
+
if (hourMatch[2]?.toLowerCase() === "pm" && hour < 12) hour += 12;
|
|
2842
|
+
if (hourMatch[2]?.toLowerCase() === "am" && hour === 12) hour = 0;
|
|
2843
|
+
}
|
|
2844
|
+
return `0 ${hour} * * *`;
|
|
2845
|
+
}
|
|
2846
|
+
const dayMap = {
|
|
2847
|
+
sunday: 0,
|
|
2848
|
+
monday: 1,
|
|
2849
|
+
tuesday: 2,
|
|
2850
|
+
wednesday: 3,
|
|
2851
|
+
thursday: 4,
|
|
2852
|
+
friday: 5,
|
|
2853
|
+
saturday: 6,
|
|
2854
|
+
sun: 0,
|
|
2855
|
+
mon: 1,
|
|
2856
|
+
tue: 2,
|
|
2857
|
+
wed: 3,
|
|
2858
|
+
thu: 4,
|
|
2859
|
+
fri: 5,
|
|
2860
|
+
sat: 6
|
|
2861
|
+
};
|
|
2862
|
+
for (const [name, num] of Object.entries(dayMap)) {
|
|
2863
|
+
if (lower.includes(name)) {
|
|
2864
|
+
const hourMatch = lower.match(/at\s*(\d{1,2})\s*(am|pm)?/i);
|
|
2865
|
+
let hour = 9;
|
|
2866
|
+
if (hourMatch) {
|
|
2867
|
+
hour = parseInt(hourMatch[1], 10);
|
|
2868
|
+
if (hourMatch[2]?.toLowerCase() === "pm" && hour < 12) hour += 12;
|
|
2869
|
+
if (hourMatch[2]?.toLowerCase() === "am" && hour === 12) hour = 0;
|
|
2870
|
+
}
|
|
2871
|
+
return `0 ${hour} * * ${num}`;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
if (/weekly/.test(lower)) return "0 9 * * 1";
|
|
2875
|
+
if (/monthly/.test(lower)) return "0 9 1 * *";
|
|
2876
|
+
if (/biweekly|bi-weekly|every\s*two\s*weeks/.test(lower)) return "0 9 1,15 * *";
|
|
2877
|
+
throw new Error(`Could not parse schedule: "${input}". Try "every friday at 9am", "daily", "weekly", or a cron expression like "0 9 * * 5".`);
|
|
2878
|
+
}
|
|
2879
|
+
var createScheduleTool = buildTool({
|
|
2880
|
+
name: "create_schedule",
|
|
2881
|
+
description: 'Create a recurring scheduled action (DCA). Supports: save, swap, repay. User says "save $50 every Friday" or "DCA $100 into savings weekly". First 5 executions require user confirmation (trust ladder), then becomes autonomous.',
|
|
2882
|
+
inputSchema: z.object({
|
|
2883
|
+
actionType: z.enum(["save", "swap", "repay"]).describe("Action type: save, swap, or repay"),
|
|
2884
|
+
amount: z.number().positive().describe("Amount in USD for each execution"),
|
|
2885
|
+
schedule: z.string().describe('Schedule description: "every friday", "daily at 9am", "weekly", or a cron expression'),
|
|
2886
|
+
asset: z.string().optional().describe("Source asset (default: USDC)"),
|
|
2887
|
+
targetAsset: z.string().optional().describe("Target asset for swaps (e.g. SUI)")
|
|
2888
|
+
}),
|
|
2889
|
+
jsonSchema: {
|
|
2890
|
+
type: "object",
|
|
2891
|
+
properties: {
|
|
2892
|
+
actionType: { type: "string", enum: ["save", "swap", "repay"], description: "Action type" },
|
|
2893
|
+
amount: { type: "number", description: "Amount in USD per execution" },
|
|
2894
|
+
schedule: { type: "string", description: 'Schedule: "every friday", "daily at 9am", "weekly", or cron' },
|
|
2895
|
+
asset: { type: "string", description: "Source asset (default: USDC)" },
|
|
2896
|
+
targetAsset: { type: "string", description: "Target asset for swaps" }
|
|
2897
|
+
},
|
|
2898
|
+
required: ["actionType", "amount", "schedule"]
|
|
2899
|
+
},
|
|
2900
|
+
isReadOnly: false,
|
|
2901
|
+
permissionLevel: "confirm",
|
|
2902
|
+
async call(input, context) {
|
|
2903
|
+
const { apiUrl, internalKey, address } = getApiConfig(context);
|
|
2904
|
+
if (!apiUrl || !address) {
|
|
2905
|
+
return { data: null, displayText: "Scheduled actions are not available." };
|
|
2906
|
+
}
|
|
2907
|
+
let cronExpr;
|
|
2908
|
+
try {
|
|
2909
|
+
cronExpr = parseCronFromDescription(input.schedule);
|
|
2910
|
+
} catch (err) {
|
|
2911
|
+
return { data: null, displayText: err instanceof Error ? err.message : "Invalid schedule format." };
|
|
2912
|
+
}
|
|
2913
|
+
try {
|
|
2914
|
+
const res = await fetch(`${apiUrl}/api/scheduled-actions`, {
|
|
2915
|
+
method: "POST",
|
|
2916
|
+
headers: {
|
|
2917
|
+
"Content-Type": "application/json",
|
|
2918
|
+
...internalKey ? { "x-internal-key": internalKey } : {}
|
|
2919
|
+
},
|
|
2920
|
+
body: JSON.stringify({
|
|
2921
|
+
address,
|
|
2922
|
+
actionType: input.actionType,
|
|
2923
|
+
amount: input.amount,
|
|
2924
|
+
asset: input.asset ?? "USDC",
|
|
2925
|
+
targetAsset: input.targetAsset,
|
|
2926
|
+
cronExpr
|
|
2927
|
+
})
|
|
2928
|
+
});
|
|
2929
|
+
if (!res.ok) {
|
|
2930
|
+
const err = await res.json().catch(() => ({}));
|
|
2931
|
+
return { data: null, displayText: `Failed to create schedule: ${err.error ?? res.statusText}` };
|
|
2932
|
+
}
|
|
2933
|
+
const { action } = await res.json();
|
|
2934
|
+
const nextRun = new Date(action.nextRunAt);
|
|
2935
|
+
const nextRunLabel = nextRun.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
|
|
2936
|
+
const verb = input.actionType === "save" ? "save" : input.actionType === "swap" ? "swap" : "repay";
|
|
2937
|
+
return {
|
|
2938
|
+
data: { id: action.id, actionType: input.actionType, amount: input.amount, cronExpr, nextRun: action.nextRunAt },
|
|
2939
|
+
displayText: `Scheduled: ${verb} $${input.amount.toFixed(2)} ${input.asset ?? "USDC"} ${input.schedule}. Next run: ${nextRunLabel}. First 5 executions require your confirmation.`
|
|
2940
|
+
};
|
|
2941
|
+
} catch (err) {
|
|
2942
|
+
return { data: null, displayText: `Schedule creation failed: ${err instanceof Error ? err.message : "unknown error"}` };
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
});
|
|
2946
|
+
var listSchedulesTool = buildTool({
|
|
2947
|
+
name: "list_schedules",
|
|
2948
|
+
description: "List all scheduled/recurring actions (DCA, auto-save, auto-repay) for the user.",
|
|
2949
|
+
inputSchema: z.object({}),
|
|
2950
|
+
jsonSchema: { type: "object", properties: {}, required: [] },
|
|
2951
|
+
isReadOnly: true,
|
|
2952
|
+
permissionLevel: "auto",
|
|
2953
|
+
async call(_input, context) {
|
|
2954
|
+
const { apiUrl, internalKey, address } = getApiConfig(context);
|
|
2955
|
+
if (!apiUrl || !address) {
|
|
2956
|
+
return { data: null, displayText: "Scheduled actions are not available." };
|
|
2957
|
+
}
|
|
2958
|
+
try {
|
|
2959
|
+
const res = await fetch(`${apiUrl}/api/scheduled-actions?address=${address}`, {
|
|
2960
|
+
headers: {
|
|
2961
|
+
...internalKey ? { "x-internal-key": internalKey } : {}
|
|
2962
|
+
}
|
|
2963
|
+
});
|
|
2964
|
+
if (!res.ok) {
|
|
2965
|
+
return { data: null, displayText: "Failed to fetch schedules." };
|
|
2966
|
+
}
|
|
2967
|
+
const { actions } = await res.json();
|
|
2968
|
+
if (actions.length === 0) {
|
|
2969
|
+
return { data: { actions: [] }, displayText: "No scheduled actions found." };
|
|
2970
|
+
}
|
|
2971
|
+
const lines = actions.map((a) => {
|
|
2972
|
+
const status = !a.enabled ? "paused" : a.confirmationsCompleted >= a.confirmationsRequired ? "autonomous" : `${a.confirmationsCompleted}/${a.confirmationsRequired} confirmed`;
|
|
2973
|
+
const next = new Date(a.nextRunAt).toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
|
|
2974
|
+
return `\u2022 ${a.actionType} $${a.amount.toFixed(2)} ${a.asset} \u2014 ${status} \u2014 next: ${next} \u2014 total: $${a.totalAmountUsdc.toFixed(2)} over ${a.totalExecutions} runs`;
|
|
2975
|
+
});
|
|
2976
|
+
return {
|
|
2977
|
+
data: { actions },
|
|
2978
|
+
displayText: `Found ${actions.length} scheduled action(s):
|
|
2979
|
+
${lines.join("\n")}`
|
|
2980
|
+
};
|
|
2981
|
+
} catch (err) {
|
|
2982
|
+
return { data: null, displayText: `Failed to list schedules: ${err instanceof Error ? err.message : "unknown error"}` };
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2986
|
+
var cancelScheduleTool = buildTool({
|
|
2987
|
+
name: "cancel_schedule",
|
|
2988
|
+
description: "Cancel or pause a scheduled action. Provide the schedule ID or describe which one to cancel.",
|
|
2989
|
+
inputSchema: z.object({
|
|
2990
|
+
scheduleId: z.string().describe("The ID of the scheduled action to cancel/pause"),
|
|
2991
|
+
action: z.enum(["delete", "pause", "resume"]).optional().describe("delete (default), pause, or resume")
|
|
2992
|
+
}),
|
|
2993
|
+
jsonSchema: {
|
|
2994
|
+
type: "object",
|
|
2995
|
+
properties: {
|
|
2996
|
+
scheduleId: { type: "string", description: "Schedule ID" },
|
|
2997
|
+
action: { type: "string", enum: ["delete", "pause", "resume"], description: "delete, pause, or resume" }
|
|
2998
|
+
},
|
|
2999
|
+
required: ["scheduleId"]
|
|
3000
|
+
},
|
|
3001
|
+
isReadOnly: false,
|
|
3002
|
+
permissionLevel: "confirm",
|
|
3003
|
+
async call(input, context) {
|
|
3004
|
+
const { apiUrl, internalKey, address } = getApiConfig(context);
|
|
3005
|
+
if (!apiUrl || !address) {
|
|
3006
|
+
return { data: null, displayText: "Scheduled actions are not available." };
|
|
3007
|
+
}
|
|
3008
|
+
const actionType = input.action ?? "delete";
|
|
3009
|
+
try {
|
|
3010
|
+
const res = await fetch(`${apiUrl}/api/scheduled-actions/${input.scheduleId}`, {
|
|
3011
|
+
method: "PATCH",
|
|
3012
|
+
headers: {
|
|
3013
|
+
"Content-Type": "application/json",
|
|
3014
|
+
...internalKey ? { "x-internal-key": internalKey } : {}
|
|
3015
|
+
},
|
|
3016
|
+
body: JSON.stringify({
|
|
3017
|
+
address,
|
|
3018
|
+
action: actionType,
|
|
3019
|
+
...actionType === "pause" ? { enabled: false } : {},
|
|
3020
|
+
...actionType === "resume" ? { enabled: true } : {}
|
|
3021
|
+
})
|
|
3022
|
+
});
|
|
3023
|
+
if (!res.ok) {
|
|
3024
|
+
const err = await res.json().catch(() => ({}));
|
|
3025
|
+
return { data: null, displayText: `Failed to ${actionType} schedule: ${err.error ?? res.statusText}` };
|
|
3026
|
+
}
|
|
3027
|
+
const label = actionType === "delete" ? "Cancelled" : actionType === "pause" ? "Paused" : "Resumed";
|
|
3028
|
+
return {
|
|
3029
|
+
data: { id: input.scheduleId, action: actionType },
|
|
3030
|
+
displayText: `${label} scheduled action ${input.scheduleId.slice(0, 8)}\u2026`
|
|
3031
|
+
};
|
|
3032
|
+
} catch (err) {
|
|
3033
|
+
return { data: null, displayText: `Failed: ${err instanceof Error ? err.message : "unknown error"}` };
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
});
|
|
2824
3037
|
var LLAMA_API2 = "https://api.llama.fi";
|
|
2825
3038
|
var YIELDS_API2 = "https://yields.llama.fi";
|
|
2826
3039
|
var COINS_API = "https://coins.llama.fi";
|
|
@@ -3137,7 +3350,8 @@ var READ_TOOLS = [
|
|
|
3137
3350
|
createInvoiceTool,
|
|
3138
3351
|
spendingAnalyticsTool,
|
|
3139
3352
|
yieldSummaryTool,
|
|
3140
|
-
activitySummaryTool
|
|
3353
|
+
activitySummaryTool,
|
|
3354
|
+
listSchedulesTool
|
|
3141
3355
|
];
|
|
3142
3356
|
var WRITE_TOOLS = [
|
|
3143
3357
|
saveDepositTool,
|
|
@@ -3150,7 +3364,9 @@ var WRITE_TOOLS = [
|
|
|
3150
3364
|
swapExecuteTool,
|
|
3151
3365
|
voloStakeTool,
|
|
3152
3366
|
voloUnstakeTool,
|
|
3153
|
-
saveContactTool
|
|
3367
|
+
saveContactTool,
|
|
3368
|
+
createScheduleTool,
|
|
3369
|
+
cancelScheduleTool
|
|
3154
3370
|
];
|
|
3155
3371
|
function getDefaultTools() {
|
|
3156
3372
|
return [...READ_TOOLS, ...WRITE_TOOLS];
|