diff options
Diffstat (limited to 'src/features/chat/logic/tool-summary.ts')
| -rw-r--r-- | src/features/chat/logic/tool-summary.ts | 19 |
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]"; } |
