Skip to content

Commit c0e89b0

Browse files
committed
Refactor tool parameter schemas (#109)
- Remove max(80) constraint from description fields\n- Restructure browseMessage parameters to flatten the action object\n- Simplify parameter validation logic\n- Improve error handling\n- Fix linting error by removing unused parameter
1 parent 5a8956c commit c0e89b0

File tree

6 files changed

+42
-71
lines changed

6 files changed

+42
-71
lines changed

packages/agent/src/tools/browser/browseMessage.ts

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,35 @@ import { errorToString } from '../../utils/errorToString.js';
66
import { sleep } from '../../utils/sleep.js';
77

88
import { filterPageContent } from './filterPageContent.js';
9-
import { browserSessions, type BrowserAction, SelectorType } from './types.js';
10-
11-
// Schema for browser action
12-
const browserActionSchema = z
13-
.object({
14-
actionType: z.enum(['goto', 'click', 'type', 'wait', 'content', 'close']),
15-
url: z
16-
.string()
17-
.url()
18-
.optional()
19-
.describe('URL to navigate to if "goto" actionType'),
20-
selector: z
21-
.string()
22-
.optional()
23-
.describe('Selector to click if "click" actionType'),
24-
selectorType: z
25-
.nativeEnum(SelectorType)
26-
.optional()
27-
.describe('Type of selector if "click" actionType'),
28-
text: z
29-
.string()
30-
.optional()
31-
.describe(
32-
'Text to type if "type" actionType, for other actionType, this is ignored',
33-
),
34-
})
35-
.describe('Browser action to perform');
9+
import { browserSessions, SelectorType } from './types.js';
3610

3711
// Main parameter schema
3812
const parameterSchema = z.object({
3913
instanceId: z.string().describe('The ID returned by browseStart'),
40-
action: browserActionSchema,
14+
actionType: z
15+
.enum(['goto', 'click', 'type', 'wait', 'content', 'close'])
16+
.describe('Browser action to perform'),
17+
url: z
18+
.string()
19+
.url()
20+
.optional()
21+
.describe('URL to navigate to if "goto" actionType'),
22+
selector: z
23+
.string()
24+
.optional()
25+
.describe('Selector to click if "click" actionType'),
26+
selectorType: z
27+
.nativeEnum(SelectorType)
28+
.optional()
29+
.describe('Type of selector if "click" actionType'),
30+
text: z
31+
.string()
32+
.optional()
33+
.describe(
34+
'Text to type if "type" actionType, for other actionType, this is ignored',
35+
),
4136
description: z
4237
.string()
43-
.max(80)
4438
.describe('The reason for this browser action (max 80 chars)'),
4539
});
4640

@@ -76,27 +70,20 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
7670
returnsJsonSchema: zodToJsonSchema(returnSchema),
7771

7872
execute: async (
79-
{ instanceId, action },
73+
{ instanceId, actionType, url, selector, selectorType, text },
8074
{ logger, pageFilter },
8175
): Promise<ReturnType> => {
8276
// Validate action format
83-
if (!action || typeof action !== 'object') {
84-
logger.error('Invalid action format: action must be an object');
85-
return {
86-
status: 'error',
87-
error: 'Invalid action format: action must be an object',
88-
};
89-
}
9077

91-
if (!action.actionType) {
78+
if (!actionType) {
9279
logger.error('Invalid action format: actionType is required');
9380
return {
9481
status: 'error',
9582
error: 'Invalid action format: actionType is required',
9683
};
9784
}
9885

99-
logger.verbose(`Executing browser action: ${action.actionType}`);
86+
logger.verbose(`Executing browser action: ${actionType}`);
10087
logger.verbose(`Webpage processing mode: ${pageFilter}`);
10188

10289
try {
@@ -107,18 +94,18 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
10794

10895
const { page } = session;
10996

110-
switch (action.actionType) {
97+
switch (actionType) {
11198
case 'goto': {
112-
if (!action.url) {
99+
if (!url) {
113100
throw new Error('URL required for goto action');
114101
}
115102

116103
try {
117104
// Try with 'domcontentloaded' first which is more reliable than 'networkidle'
118105
logger.verbose(
119-
`Navigating to ${action.url} with 'domcontentloaded' waitUntil`,
106+
`Navigating to ${url} with 'domcontentloaded' waitUntil`,
120107
);
121-
await page.goto(action.url, { waitUntil: 'domcontentloaded' });
108+
await page.goto(url, { waitUntil: 'domcontentloaded' });
122109
await sleep(3000);
123110
const content = await filterPageContent(page, pageFilter);
124111
logger.verbose(`Content: ${content}`);
@@ -133,11 +120,11 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
133120
`Failed with domcontentloaded strategy: ${errorToString(navError)}`,
134121
);
135122
logger.verbose(
136-
`Retrying navigation to ${action.url} with no waitUntil option`,
123+
`Retrying navigation to ${url} with no waitUntil option`,
137124
);
138125

139126
try {
140-
await page.goto(action.url);
127+
await page.goto(url);
141128
await sleep(3000);
142129
const content = await filterPageContent(page, pageFilter);
143130
logger.verbose(`Content: ${content}`);
@@ -153,13 +140,10 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
153140
}
154141

155142
case 'click': {
156-
if (!action.selector) {
143+
if (!selector) {
157144
throw new Error('Selector required for click action');
158145
}
159-
const clickSelector = getSelector(
160-
action.selector,
161-
action.selectorType,
162-
);
146+
const clickSelector = getSelector(selector, selectorType);
163147
await page.click(clickSelector);
164148
await sleep(1000); // Wait for any content changes after click
165149
const content = await filterPageContent(page, pageFilter);
@@ -170,26 +154,20 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
170154
}
171155

172156
case 'type': {
173-
if (!action.selector || !action.text) {
157+
if (!selector || !text) {
174158
throw new Error('Selector and text required for type action');
175159
}
176-
const typeSelector = getSelector(
177-
action.selector,
178-
action.selectorType,
179-
);
180-
await page.fill(typeSelector, action.text);
160+
const typeSelector = getSelector(selector, selectorType);
161+
await page.fill(typeSelector, text);
181162
logger.verbose(`Type action completed on selector: ${typeSelector}`);
182163
return { status: 'success' };
183164
}
184165

185166
case 'wait': {
186-
if (!action.selector) {
167+
if (!selector) {
187168
throw new Error('Selector required for wait action');
188169
}
189-
const waitSelector = getSelector(
190-
action.selector,
191-
action.selectorType,
192-
);
170+
const waitSelector = getSelector(selector, selectorType);
193171
await page.waitForSelector(waitSelector);
194172
logger.verbose(`Wait action completed for selector: ${waitSelector}`);
195173
return { status: 'success' };
@@ -211,9 +189,7 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
211189
}
212190

213191
default: {
214-
throw new Error(
215-
`Unsupported action type: ${(action as BrowserAction).actionType}`,
216-
);
192+
throw new Error(`Unsupported action type: ${actionType}`);
217193
}
218194
}
219195
} catch (error) {
@@ -226,11 +202,11 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
226202
},
227203

228204
logParameters: (
229-
{ action, description },
205+
{ actionType, description },
230206
{ logger, pageFilter = 'simple' },
231207
) => {
232208
logger.info(
233-
`Performing browser action: ${action.actionType} with ${pageFilter} processing, ${description}`,
209+
`Performing browser action: ${actionType} with ${pageFilter} processing, ${description}`,
234210
);
235211
},
236212

packages/agent/src/tools/browser/browseStart.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const parameterSchema = z.object({
1818
.describe('Default timeout in milliseconds (default: 30000)'),
1919
description: z
2020
.string()
21-
.max(80)
2221
.describe('The reason for starting this browser session (max 80 chars)'),
2322
});
2423

packages/agent/src/tools/interaction/subAgent.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { getTools } from '../getTools.js';
1212
const parameterSchema = z.object({
1313
description: z
1414
.string()
15-
.max(80)
1615
.describe("A brief description of the sub-agent's purpose (max 80 chars)"),
1716
goal: z
1817
.string()

packages/agent/src/tools/system/shellExecute.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const parameterSchema = z.object({
1515
.describe('The shell command to execute in MacOS bash format'),
1616
description: z
1717
.string()
18-
.max(80)
1918
.describe('The reason this shell command is being run (max 80 chars)'),
2019
timeout: z
2120
.number()

packages/agent/src/tools/system/shellMessage.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ const parameterSchema = z.object({
5353
.describe('Signal to send to the process (e.g., SIGTERM, SIGINT)'),
5454
description: z
5555
.string()
56-
.max(80)
5756
.describe('The reason for this shell interaction (max 80 chars)'),
5857
});
5958

packages/agent/src/tools/system/shellStart.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const parameterSchema = z.object({
2929
command: z.string().describe('The shell command to execute'),
3030
description: z
3131
.string()
32-
.max(80)
3332
.describe('The reason this shell command is being run (max 80 chars)'),
3433
timeout: z
3534
.number()

0 commit comments

Comments
 (0)