@morphllm/morphsdk 0.2.93 → 0.2.95

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.
Files changed (135) hide show
  1. package/dist/chunk-2AMEQAO2.js +46 -0
  2. package/dist/chunk-2AMEQAO2.js.map +1 -0
  3. package/dist/{chunk-EI4UKP24.js → chunk-2HMEZZKK.js} +2 -2
  4. package/dist/{chunk-EI4UKP24.js.map → chunk-2HMEZZKK.js.map} +1 -1
  5. package/dist/chunk-2VERUKO2.js +177 -0
  6. package/dist/chunk-2VERUKO2.js.map +1 -0
  7. package/dist/{chunk-VHOWYK66.js → chunk-43LQLGP6.js} +23 -33
  8. package/dist/chunk-43LQLGP6.js.map +1 -0
  9. package/dist/{chunk-LMUZ3NGC.js → chunk-73RV6EXR.js} +2 -2
  10. package/dist/{chunk-PBLPZ6AU.js → chunk-7D6TXC7X.js} +2 -2
  11. package/dist/{chunk-GU6DACME.js → chunk-O7LDZA52.js} +2 -2
  12. package/dist/{chunk-5QIWYEHJ.js → chunk-PE4KGDA6.js} +1 -8
  13. package/dist/chunk-PE4KGDA6.js.map +1 -0
  14. package/dist/{chunk-SQN4DUQS.js → chunk-Q6Y4R236.js} +26 -2
  15. package/dist/chunk-Q6Y4R236.js.map +1 -0
  16. package/dist/{chunk-PUGIOVSP.js → chunk-QAT5UVPX.js} +2 -2
  17. package/dist/{chunk-MIIJWDOQ.js → chunk-QJP62BXH.js} +166 -71
  18. package/dist/chunk-QJP62BXH.js.map +1 -0
  19. package/dist/{chunk-EYGBUH2R.js → chunk-R7IQWNSA.js} +8 -8
  20. package/dist/chunk-R7IQWNSA.js.map +1 -0
  21. package/dist/chunk-SI2CKRKJ.js +389 -0
  22. package/dist/chunk-SI2CKRKJ.js.map +1 -0
  23. package/dist/{chunk-4WLGDYWQ.js → chunk-TSENDJQI.js} +6 -6
  24. package/dist/chunk-TSENDJQI.js.map +1 -0
  25. package/dist/{chunk-IUG2FHNN.js → chunk-XH7P7HVT.js} +1 -8
  26. package/dist/chunk-XH7P7HVT.js.map +1 -0
  27. package/dist/{chunk-FNLNDMIX.js → chunk-YZ5NCWO2.js} +6 -6
  28. package/dist/chunk-YZ5NCWO2.js.map +1 -0
  29. package/dist/{chunk-IJ54DTJ3.js → chunk-ZYTAKEBW.js} +13 -13
  30. package/dist/client.cjs +770 -110
  31. package/dist/client.cjs.map +1 -1
  32. package/dist/client.d.ts +2 -0
  33. package/dist/client.js +16 -13
  34. package/dist/index.cjs +770 -110
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +16 -13
  38. package/dist/tools/browser/anthropic.cjs +58 -23
  39. package/dist/tools/browser/anthropic.cjs.map +1 -1
  40. package/dist/tools/browser/anthropic.js +7 -4
  41. package/dist/tools/browser/core.cjs +750 -70
  42. package/dist/tools/browser/core.cjs.map +1 -1
  43. package/dist/tools/browser/core.d.ts +30 -24
  44. package/dist/tools/browser/core.js +5 -2
  45. package/dist/tools/browser/errors.cjs +208 -0
  46. package/dist/tools/browser/errors.cjs.map +1 -0
  47. package/dist/tools/browser/errors.d.ts +158 -0
  48. package/dist/tools/browser/errors.js +22 -0
  49. package/dist/tools/browser/errors.js.map +1 -0
  50. package/dist/tools/browser/index.cjs +783 -85
  51. package/dist/tools/browser/index.cjs.map +1 -1
  52. package/dist/tools/browser/index.d.ts +5 -2
  53. package/dist/tools/browser/index.js +32 -9
  54. package/dist/tools/browser/index.js.map +1 -1
  55. package/dist/tools/browser/live.cjs +25 -1
  56. package/dist/tools/browser/live.cjs.map +1 -1
  57. package/dist/tools/browser/live.js +1 -1
  58. package/dist/tools/browser/openai.cjs +58 -23
  59. package/dist/tools/browser/openai.cjs.map +1 -1
  60. package/dist/tools/browser/openai.js +7 -4
  61. package/dist/tools/browser/profiles/core.cjs +670 -0
  62. package/dist/tools/browser/profiles/core.cjs.map +1 -0
  63. package/dist/tools/browser/profiles/core.d.ts +187 -0
  64. package/dist/tools/browser/profiles/core.js +29 -0
  65. package/dist/tools/browser/profiles/core.js.map +1 -0
  66. package/dist/tools/browser/profiles/index.cjs +670 -0
  67. package/dist/tools/browser/profiles/index.cjs.map +1 -0
  68. package/dist/tools/browser/profiles/index.d.ts +4 -0
  69. package/dist/tools/browser/profiles/index.js +29 -0
  70. package/dist/tools/browser/profiles/index.js.map +1 -0
  71. package/dist/tools/browser/profiles/types.cjs +74 -0
  72. package/dist/tools/browser/profiles/types.cjs.map +1 -0
  73. package/dist/tools/browser/profiles/types.d.ts +195 -0
  74. package/dist/tools/browser/profiles/types.js +16 -0
  75. package/dist/tools/browser/profiles/types.js.map +1 -0
  76. package/dist/tools/browser/prompts.cjs +1 -1
  77. package/dist/tools/browser/prompts.cjs.map +1 -1
  78. package/dist/tools/browser/prompts.d.ts +1 -1
  79. package/dist/tools/browser/prompts.js +1 -1
  80. package/dist/tools/browser/types.cjs.map +1 -1
  81. package/dist/tools/browser/types.d.ts +55 -51
  82. package/dist/tools/browser/vercel.cjs +60 -25
  83. package/dist/tools/browser/vercel.cjs.map +1 -1
  84. package/dist/tools/browser/vercel.d.ts +1 -1
  85. package/dist/tools/browser/vercel.js +7 -4
  86. package/dist/tools/fastapply/anthropic.cjs +0 -7
  87. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  88. package/dist/tools/fastapply/anthropic.js +1 -1
  89. package/dist/tools/fastapply/index.cjs +0 -14
  90. package/dist/tools/fastapply/index.cjs.map +1 -1
  91. package/dist/tools/fastapply/index.js +5 -5
  92. package/dist/tools/fastapply/openai.cjs +0 -7
  93. package/dist/tools/fastapply/openai.cjs.map +1 -1
  94. package/dist/tools/fastapply/openai.js +1 -1
  95. package/dist/tools/index.cjs +0 -14
  96. package/dist/tools/index.cjs.map +1 -1
  97. package/dist/tools/index.js +5 -5
  98. package/dist/tools/warp_grep/agent/runner.cjs +18 -98
  99. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  100. package/dist/tools/warp_grep/agent/runner.js +2 -3
  101. package/dist/tools/warp_grep/anthropic.cjs +18 -98
  102. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  103. package/dist/tools/warp_grep/anthropic.js +8 -9
  104. package/dist/tools/warp_grep/client.cjs +18 -98
  105. package/dist/tools/warp_grep/client.cjs.map +1 -1
  106. package/dist/tools/warp_grep/client.js +5 -6
  107. package/dist/tools/warp_grep/gemini.cjs +18 -98
  108. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  109. package/dist/tools/warp_grep/gemini.js +7 -8
  110. package/dist/tools/warp_grep/gemini.js.map +1 -1
  111. package/dist/tools/warp_grep/harness.js +10 -10
  112. package/dist/tools/warp_grep/index.cjs +18 -98
  113. package/dist/tools/warp_grep/index.cjs.map +1 -1
  114. package/dist/tools/warp_grep/index.js +8 -9
  115. package/dist/tools/warp_grep/openai.cjs +18 -98
  116. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  117. package/dist/tools/warp_grep/openai.js +8 -9
  118. package/dist/tools/warp_grep/vercel.cjs +18 -98
  119. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  120. package/dist/tools/warp_grep/vercel.js +8 -9
  121. package/dist/{vercel-CsnNSdze.d.ts → vercel-CVF27qFK.d.ts} +10 -10
  122. package/package.json +7 -2
  123. package/dist/chunk-4WLGDYWQ.js.map +0 -1
  124. package/dist/chunk-5QIWYEHJ.js.map +0 -1
  125. package/dist/chunk-EYGBUH2R.js.map +0 -1
  126. package/dist/chunk-FNLNDMIX.js.map +0 -1
  127. package/dist/chunk-IUG2FHNN.js.map +0 -1
  128. package/dist/chunk-MIIJWDOQ.js.map +0 -1
  129. package/dist/chunk-SQN4DUQS.js.map +0 -1
  130. package/dist/chunk-VHOWYK66.js.map +0 -1
  131. /package/dist/{chunk-LMUZ3NGC.js.map → chunk-73RV6EXR.js.map} +0 -0
  132. /package/dist/{chunk-PBLPZ6AU.js.map → chunk-7D6TXC7X.js.map} +0 -0
  133. /package/dist/{chunk-GU6DACME.js.map → chunk-O7LDZA52.js.map} +0 -0
  134. /package/dist/{chunk-PUGIOVSP.js.map → chunk-QAT5UVPX.js.map} +0 -0
  135. /package/dist/{chunk-IJ54DTJ3.js.map → chunk-ZYTAKEBW.js.map} +0 -0
@@ -7,7 +7,7 @@ import { RetryConfig } from '../utils/resilience.js';
7
7
  /**
8
8
  * Available browser automation models
9
9
  */
10
- type BrowserModel = 'gemini-3-flash-preview' | 'morph-computer-use-v0';
10
+ type BrowserModel = 'gemini-3-flash-preview' | 'morph-computer-use-v0' | 'morph-computer-use-v1';
11
11
  /**
12
12
  * Configuration for the browser worker service
13
13
  */
@@ -43,7 +43,7 @@ interface BrowserTaskInput {
43
43
  /** Starting URL (e.g., https://3000-xyz.e2b.dev) */
44
44
  url?: string;
45
45
  /** Maximum number of browser actions to take (1-50, default: 10) */
46
- max_steps?: number;
46
+ maxSteps?: number;
47
47
  /** Model to use for task execution (default: morph-computer-use-v0) */
48
48
  model?: BrowserModel;
49
49
  /** Browserless region: 'sfo' (US West) or 'lon' (Europe) */
@@ -51,32 +51,36 @@ interface BrowserTaskInput {
51
51
  /** Enable stealth mode to avoid bot detection (default: true) */
52
52
  stealth?: boolean;
53
53
  /** Browser viewport width (default: 1280) */
54
- viewport_width?: number;
54
+ viewportWidth?: number;
55
55
  /** Browser viewport height (default: 720) */
56
- viewport_height?: number;
56
+ viewportHeight?: number;
57
57
  /** User-defined reference/tracking ID (e.g., "PR-1234", "jira-PROJ-567") */
58
- external_id?: string;
59
- /** Optional repository ID to associate with this session */
60
- repo_id?: string;
58
+ externalId?: string;
59
+ /** Optional repository database ID (UUID) to associate with this session - for internal use */
60
+ repoId?: string;
61
+ /** Optional repository full name (e.g., "owner/repo") - for external SDK users */
62
+ repoFullName?: string;
61
63
  /** Optional commit UUID to associate with this session */
62
- commit_id?: string;
64
+ commitId?: string;
63
65
  /** Record session video to S3 (default: false) */
64
- record_video?: boolean;
66
+ recordVideo?: boolean;
65
67
  /** Video width (default: 1280) */
66
- video_width?: number;
68
+ videoWidth?: number;
67
69
  /** Video height (default: 720) */
68
- video_height?: number;
70
+ videoHeight?: number;
69
71
  /** Enable window resizing for responsive/mobile testing. Disables stealth mode. (default: false) */
70
- allow_resizing?: boolean;
72
+ allowResizing?: boolean;
71
73
  /** Serialized structured output schema (internal use) */
72
- structured_output?: string;
74
+ structuredOutput?: string;
73
75
  /** Site authentication - global credentials or per-domain dict (follows browser-use pattern) */
74
76
  auth?: AuthCredentials | Record<string, AuthCredentials>;
77
+ /** Profile ID - restore cookies/localStorage from a saved browser profile */
78
+ profileId?: string;
75
79
  }
76
80
  /**
77
81
  * Input with Zod schema for structured output
78
82
  */
79
- interface BrowserTaskInputWithSchema<T> extends Omit<BrowserTaskInput, 'structured_output'> {
83
+ interface BrowserTaskInputWithSchema<T> extends Omit<BrowserTaskInput, 'structuredOutput'> {
80
84
  /** Zod schema for structured output */
81
85
  schema: any;
82
86
  }
@@ -91,27 +95,27 @@ interface BrowserTaskResult {
91
95
  /** Error message if task failed */
92
96
  error?: string;
93
97
  /** Number of browser actions taken */
94
- steps_taken?: number;
98
+ stepsTaken?: number;
95
99
  /** Total execution time in milliseconds */
96
- execution_time_ms?: number;
100
+ executionTimeMs?: number;
97
101
  /** All URLs visited during execution */
98
102
  urls?: (string | null)[];
99
103
  /** Names of all actions executed */
100
- action_names?: string[];
104
+ actionNames?: string[];
101
105
  /** Per-step errors (null for steps without errors) */
102
106
  errors?: (string | null)[];
103
107
  /** All model actions with parameters */
104
- model_actions?: any[];
108
+ modelActions?: any[];
105
109
  /** Whether agent marked task as done */
106
- is_done?: boolean;
110
+ isDone?: boolean;
107
111
  /** Truncated action history with essential fields */
108
- action_history?: any[][];
112
+ actionHistory?: any[][];
109
113
  /** All action results */
110
- action_results?: any[];
114
+ actionResults?: any[];
111
115
  /** Whether any errors occurred */
112
- has_errors?: boolean;
116
+ hasErrors?: boolean;
113
117
  /** Total number of steps executed */
114
- number_of_steps?: number;
118
+ numberOfSteps?: number;
115
119
  /** Judge validation result if available */
116
120
  judgement?: {
117
121
  reasoning?: string;
@@ -121,17 +125,17 @@ interface BrowserTaskResult {
121
125
  reached_captcha?: boolean;
122
126
  };
123
127
  /** Whether judge validated the execution */
124
- is_validated?: boolean;
128
+ isValidated?: boolean;
125
129
  /** UUID of saved replay record (if session replay enabled) */
126
- replay_id?: string;
130
+ replayId?: string;
127
131
  /** Browserless replay URL (if session replay enabled) */
128
- replay_url?: string;
129
- /** Recording ID (if record_video=true) */
130
- recording_id?: string;
132
+ replayUrl?: string;
133
+ /** Recording ID (if recordVideo=true) */
134
+ recordingId?: string;
131
135
  /** Recording status: PENDING, PROCESSING, COMPLETED, ERROR */
132
- recording_status?: string;
136
+ recordingStatus?: string;
133
137
  /** Task ID for async task tracking */
134
- task_id?: string;
138
+ taskId?: string;
135
139
  /** Task status: pending, running, completed, failed */
136
140
  status?: string;
137
141
  /** Structured output (JSON string) */
@@ -171,7 +175,7 @@ interface IframeOptions extends LiveSessionOptions {
171
175
  * Task result with convenience methods for async execution
172
176
  */
173
177
  interface BrowserTaskWithPromise extends BrowserTaskResult {
174
- task_id: string;
178
+ taskId: string;
175
179
  /** Live URL to watch task execution in real-time */
176
180
  liveUrl: string;
177
181
  /** Wait for task completion */
@@ -190,7 +194,7 @@ interface BrowserTaskWithPromise extends BrowserTaskResult {
190
194
  * Task result with schema validation
191
195
  */
192
196
  interface BrowserTaskWithPromiseAndSchema<T> extends BrowserTaskResult {
193
- task_id: string;
197
+ taskId: string;
194
198
  /** Live URL to watch task execution in real-time */
195
199
  liveUrl: string;
196
200
  /** Parsed and validated output */
@@ -218,23 +222,23 @@ interface RecordingStatus {
218
222
  /** Current status */
219
223
  status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'ERROR';
220
224
  /** Presigned S3 URL for rrweb replay JSON (interactive DOM replay) */
221
- replay_url?: string;
225
+ replayUrl?: string;
222
226
  /** Presigned S3 URL for network logs (NDJSON format) */
223
- network_url?: string;
227
+ networkUrl?: string;
224
228
  /** Presigned S3 URL for console logs (NDJSON format) */
225
- console_url?: string;
229
+ consoleUrl?: string;
226
230
  /** Presigned S3 URL for native browser video (WebM or MP4 format, real-time recording) */
227
- video_url?: string;
231
+ videoUrl?: string;
228
232
  /** Total rrweb events captured */
229
- total_events?: number;
233
+ totalEvents?: number;
230
234
  /** Total bytes of all files */
231
- file_size?: number;
235
+ fileSize?: number;
232
236
  /** Duration in milliseconds */
233
237
  duration?: number;
234
238
  /** Error message if status=ERROR */
235
239
  error?: string;
236
240
  /** When recording was created */
237
- created_at: string;
241
+ createdAt: string;
238
242
  }
239
243
  /**
240
244
  * Browser error with screenshot captured at error time
@@ -249,9 +253,9 @@ interface BrowserError {
249
253
  /** CDP timestamp in seconds since browser start */
250
254
  timestamp: number;
251
255
  /** Presigned S3 URL to screenshot JPEG (captured 500ms after error) */
252
- screenshot_url?: string;
256
+ screenshotUrl?: string;
253
257
  /** When screenshot was captured (Unix timestamp) */
254
- captured_at?: number;
258
+ capturedAt?: number;
255
259
  /** HTTP status code (for network errors) */
256
260
  status?: number;
257
261
  }
@@ -260,9 +264,9 @@ interface BrowserError {
260
264
  */
261
265
  interface ErrorsResponse {
262
266
  /** Recording ID */
263
- recording_id: string;
267
+ recordingId: string;
264
268
  /** Total number of errors */
265
- total_errors: number;
269
+ totalErrors: number;
266
270
  /** Errors with real-time screenshots */
267
271
  errors: BrowserError[];
268
272
  }
@@ -271,7 +275,7 @@ interface ErrorsResponse {
271
275
  */
272
276
  interface WebpOptions {
273
277
  /** Maximum duration in seconds (1-120, default: 60) */
274
- max_duration?: number;
278
+ maxDuration?: number;
275
279
  /** Frame rate (5-30, default: 15) */
276
280
  fps?: number;
277
281
  /** Output width in pixels (320-1920, default: 780) */
@@ -281,14 +285,14 @@ interface WebpOptions {
281
285
  /** Enable auto-zoom that follows click/input actions (default: false) */
282
286
  autoZoom?: boolean;
283
287
  /** Maximum file size in MB (0.5-50). Uses iterative reduction to guarantee budget. */
284
- max_size_mb?: number;
288
+ maxSizeMb?: number;
285
289
  }
286
290
  /**
287
291
  * Response from getWebp()
288
292
  */
289
293
  interface WebpResponse {
290
294
  /** Presigned S3 URL for the WebP file */
291
- webp_url: string;
295
+ webpUrl: string;
292
296
  /** Whether the WebP was served from cache */
293
297
  cached: boolean;
294
298
  /** Width of the WebP (may differ from requested if budget-constrained) */
@@ -296,15 +300,15 @@ interface WebpResponse {
296
300
  /** Frame rate of the WebP (may differ from requested if budget-constrained) */
297
301
  fps: number;
298
302
  /** Max duration used (may differ from requested if budget-constrained) */
299
- max_duration: number;
303
+ maxDuration: number;
300
304
  /** File size in bytes */
301
- file_size?: number;
305
+ fileSize?: number;
302
306
  /** Max size budget in MB (if specified) */
303
- max_size_mb?: number;
307
+ maxSizeMb?: number;
304
308
  /** Whether the file fits within the budget */
305
- budget_met?: boolean;
309
+ budgetMet?: boolean;
306
310
  /** Quality setting used (may differ from requested if budget-constrained) */
307
- quality_used?: number;
311
+ qualityUsed?: number;
308
312
  /** Number of encoding attempts needed to meet budget */
309
313
  attempts?: number;
310
314
  }
@@ -101,6 +101,9 @@ function sleep(ms) {
101
101
  return new Promise((resolve) => setTimeout(resolve, ms));
102
102
  }
103
103
 
104
+ // tools/browser/profiles/core.ts
105
+ var DEFAULT_API_URL = process.env.MORPH_ENVIRONMENT === "DEV" ? "http://localhost:8000" : "https://browser.morphllm.com";
106
+
104
107
  // tools/browser/core.ts
105
108
  var DEFAULT_CONFIG = {
106
109
  apiUrl: process.env.MORPH_ENVIRONMENT === "DEV" ? "http://localhost:8000" : "https://browser.morphllm.com",
@@ -118,15 +121,15 @@ async function executeBrowserTask(input, config = {}) {
118
121
  error: 'Task description is required. Example: "Go to example.com and click the login button"'
119
122
  };
120
123
  }
121
- if (input.max_steps !== void 0 && (input.max_steps < 1 || input.max_steps > 50)) {
124
+ if (input.maxSteps !== void 0 && (input.maxSteps < 1 || input.maxSteps > 50)) {
122
125
  return {
123
126
  success: false,
124
- error: "max_steps must be between 1 and 50. Use more steps for complex multi-page flows."
127
+ error: "maxSteps must be between 1 and 50. Use more steps for complex multi-page flows."
125
128
  };
126
129
  }
127
130
  if (debug) {
128
- console.log(`[Browser] Task: "${input.task.slice(0, 60)}..." url=${input.url || "none"} maxSteps=${input.max_steps ?? 10}`);
129
- console.log(`[Browser] Recording: ${input.record_video ? "yes" : "no"} | Calling ${apiUrl}/browser-task`);
131
+ console.log(`[Browser] Task: "${input.task.slice(0, 60)}..." url=${input.url || "none"} maxSteps=${input.maxSteps ?? 10}`);
132
+ console.log(`[Browser] Recording: ${input.recordVideo ? "yes" : "no"} | Calling ${apiUrl}/browser-task`);
130
133
  }
131
134
  const startTime = Date.now();
132
135
  try {
@@ -140,19 +143,20 @@ async function executeBrowserTask(input, config = {}) {
140
143
  body: JSON.stringify({
141
144
  task: input.task,
142
145
  url: input.url,
143
- max_steps: input.max_steps ?? 10,
146
+ max_steps: input.maxSteps ?? 10,
144
147
  model: input.model ?? "morph-computer-use-v0",
145
- viewport_width: input.viewport_width ?? 1280,
146
- viewport_height: input.viewport_height ?? 720,
147
- external_id: input.external_id,
148
- repo_id: input.repo_id,
149
- commit_id: input.commit_id,
150
- record_video: input.record_video ?? false,
151
- video_width: input.video_width ?? input.viewport_width ?? 1280,
152
- video_height: input.video_height ?? input.viewport_height ?? 720,
153
- allow_resizing: input.allow_resizing ?? false,
154
- structured_output: input.structured_output,
155
- auth: input.auth
148
+ viewport_width: input.viewportWidth ?? 1280,
149
+ viewport_height: input.viewportHeight ?? 720,
150
+ external_id: input.externalId,
151
+ repo_id: input.repoId,
152
+ commit_id: input.commitId,
153
+ record_video: input.recordVideo ?? false,
154
+ video_width: input.videoWidth ?? input.viewportWidth ?? 1280,
155
+ video_height: input.videoHeight ?? input.viewportHeight ?? 720,
156
+ allow_resizing: input.allowResizing ?? false,
157
+ structured_output: input.structuredOutput,
158
+ auth: input.auth,
159
+ profile_id: input.profileId
156
160
  })
157
161
  },
158
162
  config.retryConfig
@@ -160,17 +164,17 @@ async function executeBrowserTask(input, config = {}) {
160
164
  const response = await withTimeout(
161
165
  fetchPromise,
162
166
  timeout,
163
- `Browser task timed out after ${timeout}ms. Consider increasing timeout or reducing max_steps.`
167
+ `Browser task timed out after ${timeout}ms. Consider increasing timeout or reducing maxSteps.`
164
168
  );
165
169
  if (!response.ok) {
166
170
  const errorText = await response.text().catch(() => response.statusText);
167
171
  if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
168
172
  throw new Error(`HTTP ${response.status}: ${errorText}`);
169
173
  }
170
- const result = await response.json();
174
+ const result = mapTaskResult(await response.json());
171
175
  const elapsed = Date.now() - startTime;
172
176
  if (debug) {
173
- console.log(`[Browser] \u2705 ${result.success ? "Success" : "Failed"} in ${elapsed}ms | steps=${result.steps_taken ?? 0} recordingId=${result.recording_id ?? "none"}`);
177
+ console.log(`[Browser] \u2705 ${result.success ? "Success" : "Failed"} in ${elapsed}ms | steps=${result.stepsTaken ?? 0} recordingId=${result.recordingId ?? "none"}`);
174
178
  }
175
179
  return result;
176
180
  } catch (error) {
@@ -192,6 +196,37 @@ async function executeBrowserTask(input, config = {}) {
192
196
  };
193
197
  }
194
198
  }
199
+ function mapTaskResult(api) {
200
+ if (!api || typeof api !== "object") {
201
+ return api;
202
+ }
203
+ return {
204
+ success: api.success,
205
+ result: api.result,
206
+ error: api.error,
207
+ stepsTaken: api.steps_taken,
208
+ executionTimeMs: api.execution_time_ms,
209
+ urls: api.urls,
210
+ actionNames: api.action_names,
211
+ errors: api.errors,
212
+ modelActions: api.model_actions,
213
+ isDone: api.is_done,
214
+ actionHistory: api.action_history,
215
+ actionResults: api.action_results,
216
+ hasErrors: api.has_errors,
217
+ numberOfSteps: api.number_of_steps,
218
+ judgement: api.judgement,
219
+ isValidated: api.is_validated,
220
+ replayId: api.replay_id,
221
+ replayUrl: api.replay_url,
222
+ recordingId: api.recording_id,
223
+ recordingStatus: api.recording_status,
224
+ taskId: api.task_id,
225
+ status: api.status,
226
+ output: api.output,
227
+ debugUrl: api.debug_url
228
+ };
229
+ }
195
230
 
196
231
  // tools/browser/prompts.ts
197
232
  var BROWSER_TOOL_DESCRIPTION = `Test and verify your implemented code in a live browser. This tool executes natural language test instructions and returns a video recording plus detailed logs to help you debug issues.
@@ -229,31 +264,31 @@ Include verification steps:
229
264
  ## Requirements
230
265
  - **URL**: Must be publicly accessible (use tunnels like ngrok, Cloudflare, or deploy to staging)
231
266
  - **Timing**: Use this after implementation, not during coding
232
- - **Complexity**: Set max_steps higher (20-30) for multi-step user workflows`;
267
+ - **Complexity**: Set maxSteps higher (20-30) for multi-step user workflows`;
233
268
 
234
269
  // tools/browser/vercel.ts
235
270
  function createBrowserTool(config) {
236
271
  const schema = import_zod.z.object({
237
272
  task: import_zod.z.string().describe('Natural language description of what to do (e.g., "Test checkout flow for buying a pineapple")'),
238
273
  url: import_zod.z.string().optional().describe("Starting URL (e.g., https://3000-xyz.e2b.dev)"),
239
- max_steps: import_zod.z.number().min(1).max(50).default(10).describe("Maximum number of browser actions to take"),
274
+ maxSteps: import_zod.z.number().min(1).max(50).default(10).describe("Maximum number of browser actions to take"),
240
275
  region: import_zod.z.enum(["sfo", "lon"]).default("sfo").describe("Browserless region: sfo (US West) or lon (Europe)")
241
276
  });
242
277
  return (0, import_ai.tool)({
243
278
  description: BROWSER_TOOL_DESCRIPTION,
244
279
  inputSchema: schema,
245
280
  execute: async (params) => {
246
- const { task, url, max_steps, region } = params;
281
+ const { task, url, maxSteps, region } = params;
247
282
  const result = await executeBrowserTask(
248
- { task, url, max_steps, region },
283
+ { task, url, maxSteps, region },
249
284
  config
250
285
  );
251
286
  if (result.success) {
252
287
  return {
253
288
  success: true,
254
289
  result: result.result,
255
- steps_taken: result.steps_taken,
256
- execution_time_ms: result.execution_time_ms
290
+ stepsTaken: result.stepsTaken,
291
+ executionTimeMs: result.executionTimeMs
257
292
  };
258
293
  }
259
294
  return {