@t2000/engine 0.43.0 → 0.45.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.js CHANGED
@@ -181,14 +181,13 @@ function budgetToolResult(data, tool) {
181
181
  }
182
182
  const preview = serialized.slice(0, tool.maxResultSizeChars);
183
183
  const linesOmitted = serialized.split("\n").length - preview.split("\n").length;
184
- const truncated = `${preview}
185
-
186
- [Truncated \u2014 ${linesOmitted} lines omitted. Call ${tool.name} with narrower parameters (e.g. smaller date range or limit) to see more.]`;
187
- try {
188
- return JSON.parse(truncated);
189
- } catch {
190
- return truncated;
184
+ const note = `[Truncated \u2014 ${linesOmitted} lines omitted. Call ${tool.name} with narrower parameters (e.g. smaller date range or limit) to see more.]`;
185
+ if (typeof data === "object" && data !== null) {
186
+ return { _truncated: true, _preview: preview, _note: note };
191
187
  }
188
+ return `${preview}
189
+
190
+ ${note}`;
192
191
  }
193
192
 
194
193
  // src/tool-flags.ts
@@ -1013,6 +1012,34 @@ var KNOWN_TARGETS = [
1013
1012
  [/::deepbook/, "swap"],
1014
1013
  [/::transfer::public_transfer/, "send"]
1015
1014
  ];
1015
+ var LABEL_PATTERNS = [
1016
+ [/::pay(?:ment_kit|_kit)?::|::create_payment_link|::pay_link/, "payment_link"],
1017
+ [/::create_invoice|::invoice::/, "invoice"],
1018
+ [/::deposit|::supply|::mint_ctokens/, "deposit"],
1019
+ [/::withdraw|::redeem|::redeem_ctokens/, "withdraw"],
1020
+ [/::borrow/, "borrow"],
1021
+ [/::repay/, "repay"],
1022
+ [/::claim_reward|::claim::|::claim_incentive/, "claim"],
1023
+ [/::stake/, "stake"],
1024
+ [/::unstake|::burn::/, "unstake"],
1025
+ [/::liquidate/, "liquidate"]
1026
+ ];
1027
+ function fallbackLabel(targets) {
1028
+ if (!targets.length) return "on-chain";
1029
+ const first = targets[0];
1030
+ const parts = first.split("::");
1031
+ if (parts.length >= 2 && parts[1]) return parts[1].toLowerCase();
1032
+ return "on-chain";
1033
+ }
1034
+ function classifyLabel(targets, commandTypes) {
1035
+ for (const target of targets) {
1036
+ for (const [pattern, label] of LABEL_PATTERNS) {
1037
+ if (pattern.test(target)) return label;
1038
+ }
1039
+ }
1040
+ if (commandTypes.includes("TransferObjects") && !commandTypes.includes("MoveCall")) return "send";
1041
+ return fallbackLabel(targets);
1042
+ }
1016
1043
  function resolveOwner(owner) {
1017
1044
  if (typeof owner === "object" && owner.AddressOwner) return owner.AddressOwner;
1018
1045
  if (typeof owner === "string") return owner;
@@ -1065,9 +1092,23 @@ function parseRpcTx(tx, address) {
1065
1092
  recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? void 0 : void 0;
1066
1093
  }
1067
1094
  const timestampMs = Number(tx.timestampMs ?? 0);
1095
+ const action = classifyAction(moveCallTargets, commandTypes);
1096
+ let label = classifyLabel(moveCallTargets, commandTypes);
1097
+ const labelMatchedSpecific = LABEL_PATTERNS.some(([p]) => moveCallTargets.some((t) => p.test(t)));
1098
+ if (action === "lending" && !labelMatchedSpecific) {
1099
+ const userNonSuiOutflow = changes.find(
1100
+ (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) < 0n
1101
+ );
1102
+ const userNonSuiInflow = changes.find(
1103
+ (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) > 0n
1104
+ );
1105
+ if (userNonSuiOutflow) label = "deposit";
1106
+ else if (userNonSuiInflow) label = "withdraw";
1107
+ }
1068
1108
  return {
1069
1109
  digest: tx.digest,
1070
- action: classifyAction(moveCallTargets, commandTypes),
1110
+ action,
1111
+ label,
1071
1112
  amount,
1072
1113
  asset,
1073
1114
  recipient,
@@ -1166,6 +1207,42 @@ var transactionHistoryTool = buildTool({
1166
1207
  // `date` filter the dedupe is wrong post-write because the just-
1167
1208
  // executed write may now be in history. Never dedupe.
1168
1209
  cacheable: false,
1210
+ /**
1211
+ * [v1.5.2] Custom truncation that preserves the structured shape.
1212
+ *
1213
+ * The default `budgetToolResult` slices the JSON string at the byte
1214
+ * limit, appends a "[Truncated…]" note, and tries `JSON.parse` — which
1215
+ * always fails for sliced JSON, so the engine falls back to returning
1216
+ * the raw string. The frontend's `transaction_history` card renderer
1217
+ * then sees `typeof data !== 'object'` and bails, so the rich card
1218
+ * never renders even though the LLM has the full text.
1219
+ *
1220
+ * Strategy: progressively halve the `transactions` array until the
1221
+ * serialized payload fits, then stamp `_truncated: true` and the
1222
+ * original length so the LLM knows to recall with `limit` if it needs
1223
+ * older entries. Result is always valid JSON, always object-shaped.
1224
+ */
1225
+ summarizeOnTruncate(serialized, maxChars) {
1226
+ let parsed;
1227
+ try {
1228
+ parsed = JSON.parse(serialized);
1229
+ } catch {
1230
+ return JSON.stringify({
1231
+ transactions: [],
1232
+ count: 0,
1233
+ _truncated: true,
1234
+ _note: "Result exceeded size budget and could not be summarized."
1235
+ });
1236
+ }
1237
+ const original = Array.isArray(parsed.transactions) ? parsed.transactions : [];
1238
+ let trimmed = original.slice();
1239
+ let payload = JSON.stringify({ ...parsed, transactions: trimmed, _truncated: true, _originalCount: original.length });
1240
+ while (payload.length > maxChars && trimmed.length > 1) {
1241
+ trimmed = trimmed.slice(0, Math.max(1, Math.floor(trimmed.length / 2)));
1242
+ payload = JSON.stringify({ ...parsed, transactions: trimmed, _truncated: true, _originalCount: original.length });
1243
+ }
1244
+ return payload;
1245
+ },
1169
1246
  async call(input, context) {
1170
1247
  const limit = input.limit ?? 10;
1171
1248
  const action = input.action;