Skip to content

Commit 864287e

Browse files
committed
circle detection, replace instances with string representation
1 parent fed35b9 commit 864287e

1 file changed

Lines changed: 23 additions & 18 deletions

File tree

src/tools/inPage.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -156,48 +156,53 @@ export const executeInPageTool = definePageTool({
156156
};
157157
};
158158

159+
const ancestors: unknown[] = [];
159160
// Recursively walks the tool result:
160-
// - Replaces DOM elements with UIDs
161-
// - Replaces functions with the string 'function'
162-
// - Removes items which are deeper than cutoff
161+
// - Replaces DOM elements with an ID and stashes the DOM element on the window object
162+
// - Replaces non-plain-objects with a string representation of the object
163+
// - Replaces circular references with the string '<Circular reference>'
164+
// - Replaces functions with the string '<Function object>'
163165
const processToolResult = (
164166
data: unknown,
165-
depth = 0,
166-
cutoff = 8,
167+
parentEl?: unknown,
167168
): unknown => {
168-
if (depth >= cutoff) {
169-
return undefined;
170-
}
171-
172169
// 1. Handle DOM Elements
173170
if (data instanceof Element) {
174171
return stashDOMElement(data);
175172
}
176173

177174
// 2. Handle Arrays
178175
if (Array.isArray(data)) {
179-
if (depth >= cutoff - 1) {
180-
return [];
181-
}
182176
return data.map((item: unknown) =>
183-
processToolResult(item, depth + 1, cutoff),
177+
processToolResult(item, parentEl),
184178
);
185179
}
186180

187181
// 3. Handle Objects
188182
if (data !== null && typeof data === 'object') {
183+
while (ancestors.length > 0 && ancestors.at(-1) !== parentEl) {
184+
ancestors.pop();
185+
}
186+
if (ancestors.includes(data)) {
187+
return '<Circular reference>';
188+
}
189+
ancestors.push(data);
190+
191+
// If not a plain object, return a string representation of the object
192+
if (Object.getPrototypeOf(data) !== Object.prototype) {
193+
return `<${data.constructor.name} instance>`;
194+
}
195+
189196
const processedObj: Record<string, unknown> = {};
190-
if (depth < cutoff - 1) {
191-
for (const [key, value] of Object.entries(data)) {
192-
processedObj[key] = processToolResult(value, depth + 1, cutoff);
193-
}
197+
for (const [key, value] of Object.entries(data)) {
198+
processedObj[key] = processToolResult(value, data);
194199
}
195200
return processedObj;
196201
}
197202

198203
// 4. Handle Functions
199204
if (typeof data === 'function') {
200-
return 'function';
205+
return '<Function object>';
201206
}
202207

203208
// 5. Return primitives (strings, numbers, booleans) as-is

0 commit comments

Comments
 (0)