@t2000/engine 0.43.0 → 0.44.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
@@ -1166,6 +1165,42 @@ var transactionHistoryTool = buildTool({
1166
1165
  // `date` filter the dedupe is wrong post-write because the just-
1167
1166
  // executed write may now be in history. Never dedupe.
1168
1167
  cacheable: false,
1168
+ /**
1169
+ * [v1.5.2] Custom truncation that preserves the structured shape.
1170
+ *
1171
+ * The default `budgetToolResult` slices the JSON string at the byte
1172
+ * limit, appends a "[Truncated…]" note, and tries `JSON.parse` — which
1173
+ * always fails for sliced JSON, so the engine falls back to returning
1174
+ * the raw string. The frontend's `transaction_history` card renderer
1175
+ * then sees `typeof data !== 'object'` and bails, so the rich card
1176
+ * never renders even though the LLM has the full text.
1177
+ *
1178
+ * Strategy: progressively halve the `transactions` array until the
1179
+ * serialized payload fits, then stamp `_truncated: true` and the
1180
+ * original length so the LLM knows to recall with `limit` if it needs
1181
+ * older entries. Result is always valid JSON, always object-shaped.
1182
+ */
1183
+ summarizeOnTruncate(serialized, maxChars) {
1184
+ let parsed;
1185
+ try {
1186
+ parsed = JSON.parse(serialized);
1187
+ } catch {
1188
+ return JSON.stringify({
1189
+ transactions: [],
1190
+ count: 0,
1191
+ _truncated: true,
1192
+ _note: "Result exceeded size budget and could not be summarized."
1193
+ });
1194
+ }
1195
+ const original = Array.isArray(parsed.transactions) ? parsed.transactions : [];
1196
+ let trimmed = original.slice();
1197
+ let payload = JSON.stringify({ ...parsed, transactions: trimmed, _truncated: true, _originalCount: original.length });
1198
+ while (payload.length > maxChars && trimmed.length > 1) {
1199
+ trimmed = trimmed.slice(0, Math.max(1, Math.floor(trimmed.length / 2)));
1200
+ payload = JSON.stringify({ ...parsed, transactions: trimmed, _truncated: true, _originalCount: original.length });
1201
+ }
1202
+ return payload;
1203
+ },
1169
1204
  async call(input, context) {
1170
1205
  const limit = input.limit ?? 10;
1171
1206
  const action = input.action;