summaryrefslogtreecommitdiffhomepage
path: root/src/features/chat/logic/tool-summary.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/chat/logic/tool-summary.ts')
-rw-r--r--src/features/chat/logic/tool-summary.ts19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/features/chat/logic/tool-summary.ts b/src/features/chat/logic/tool-summary.ts
index f6d1569..2380adc 100644
--- a/src/features/chat/logic/tool-summary.ts
+++ b/src/features/chat/logic/tool-summary.ts
@@ -74,7 +74,24 @@ function asArgs(input: unknown): Args {
function serialize(input: unknown, pretty = false): string {
if (typeof input === "string") return input;
try {
- return JSON.stringify(input, null, pretty ? 2 : undefined) ?? String(input);
+ // Detect ancestor cycles before the native serializer recurses. Bun's
+ // pretty JSON cycle detection can otherwise consume seconds of UI time.
+ // Track ancestors, not every visited object: shared non-cyclic values are valid.
+ const ancestors: object[] = [];
+ return (
+ JSON.stringify(
+ input,
+ function (this: unknown, _key, value: unknown) {
+ if (value !== null && typeof value === "object") {
+ while (ancestors.length && ancestors.at(-1) !== this) ancestors.pop();
+ if (ancestors.includes(value)) throw new TypeError("Circular tool input");
+ ancestors.push(value);
+ }
+ return value;
+ },
+ pretty ? 2 : undefined,
+ ) ?? String(input)
+ );
} catch {
return "[unserializable input]";
}