digital-workers 2.1.3 → 2.4.0

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 (183) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +2 -0
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +33 -21
  6. package/dist/actions.js.map +1 -1
  7. package/dist/agent-comms.d.ts.map +1 -1
  8. package/dist/agent-comms.js +36 -25
  9. package/dist/agent-comms.js.map +1 -1
  10. package/dist/approve.d.ts +40 -8
  11. package/dist/approve.d.ts.map +1 -1
  12. package/dist/approve.js +86 -20
  13. package/dist/approve.js.map +1 -1
  14. package/dist/ask.d.ts +38 -7
  15. package/dist/ask.d.ts.map +1 -1
  16. package/dist/ask.js +85 -25
  17. package/dist/ask.js.map +1 -1
  18. package/dist/browse.d.ts +223 -0
  19. package/dist/browse.d.ts.map +1 -0
  20. package/dist/browse.js +392 -0
  21. package/dist/browse.js.map +1 -0
  22. package/dist/capability-tiers.js +3 -3
  23. package/dist/capability-tiers.js.map +1 -1
  24. package/dist/cascade-context.d.ts +28 -28
  25. package/dist/client.d.ts +162 -0
  26. package/dist/client.d.ts.map +1 -0
  27. package/dist/client.js +64 -0
  28. package/dist/client.js.map +1 -0
  29. package/dist/decide.d.ts +42 -6
  30. package/dist/decide.d.ts.map +1 -1
  31. package/dist/decide.js +54 -11
  32. package/dist/decide.js.map +1 -1
  33. package/dist/do.d.ts +36 -7
  34. package/dist/do.d.ts.map +1 -1
  35. package/dist/do.js +82 -39
  36. package/dist/do.js.map +1 -1
  37. package/dist/error-escalation.d.ts.map +1 -1
  38. package/dist/error-escalation.js +38 -38
  39. package/dist/error-escalation.js.map +1 -1
  40. package/dist/generate.d.ts +48 -7
  41. package/dist/generate.d.ts.map +1 -1
  42. package/dist/generate.js +49 -8
  43. package/dist/generate.js.map +1 -1
  44. package/dist/goals.d.ts +10 -9
  45. package/dist/goals.d.ts.map +1 -1
  46. package/dist/goals.js +30 -24
  47. package/dist/goals.js.map +1 -1
  48. package/dist/image.d.ts +189 -0
  49. package/dist/image.d.ts.map +1 -0
  50. package/dist/image.js +528 -0
  51. package/dist/image.js.map +1 -0
  52. package/dist/index.d.ts +49 -2
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +58 -2
  55. package/dist/index.js.map +1 -1
  56. package/dist/is.d.ts +45 -10
  57. package/dist/is.d.ts.map +1 -1
  58. package/dist/is.js +56 -21
  59. package/dist/is.js.map +1 -1
  60. package/dist/kpis.d.ts +24 -15
  61. package/dist/kpis.d.ts.map +1 -1
  62. package/dist/kpis.js +16 -14
  63. package/dist/kpis.js.map +1 -1
  64. package/dist/load-balancing.d.ts.map +1 -1
  65. package/dist/load-balancing.js +124 -38
  66. package/dist/load-balancing.js.map +1 -1
  67. package/dist/logger.d.ts +76 -0
  68. package/dist/logger.d.ts.map +1 -0
  69. package/dist/logger.js +39 -0
  70. package/dist/logger.js.map +1 -0
  71. package/dist/notify.d.ts +38 -9
  72. package/dist/notify.d.ts.map +1 -1
  73. package/dist/notify.js +72 -17
  74. package/dist/notify.js.map +1 -1
  75. package/dist/role.d.ts +5 -4
  76. package/dist/role.d.ts.map +1 -1
  77. package/dist/role.js +13 -10
  78. package/dist/role.js.map +1 -1
  79. package/dist/runtime.d.ts +310 -0
  80. package/dist/runtime.d.ts.map +1 -0
  81. package/dist/runtime.js +510 -0
  82. package/dist/runtime.js.map +1 -0
  83. package/dist/team.d.ts +11 -6
  84. package/dist/team.d.ts.map +1 -1
  85. package/dist/team.js +22 -15
  86. package/dist/team.js.map +1 -1
  87. package/dist/transports/email.d.ts +318 -0
  88. package/dist/transports/email.d.ts.map +1 -0
  89. package/dist/transports/email.js +779 -0
  90. package/dist/transports/email.js.map +1 -0
  91. package/dist/transports/slack.d.ts +515 -0
  92. package/dist/transports/slack.d.ts.map +1 -0
  93. package/dist/transports/slack.js +844 -0
  94. package/dist/transports/slack.js.map +1 -0
  95. package/dist/transports.d.ts.map +1 -1
  96. package/dist/transports.js +44 -25
  97. package/dist/transports.js.map +1 -1
  98. package/dist/types.d.ts +141 -19
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +5 -0
  101. package/dist/types.js.map +1 -1
  102. package/dist/utils/id.d.ts +19 -0
  103. package/dist/utils/id.d.ts.map +1 -0
  104. package/dist/utils/id.js +21 -0
  105. package/dist/utils/id.js.map +1 -0
  106. package/dist/video.d.ts +203 -0
  107. package/dist/video.d.ts.map +1 -0
  108. package/dist/video.js +528 -0
  109. package/dist/video.js.map +1 -0
  110. package/dist/worker.d.ts +343 -0
  111. package/dist/worker.d.ts.map +1 -0
  112. package/dist/worker.js +698 -0
  113. package/dist/worker.js.map +1 -0
  114. package/package.json +32 -14
  115. package/src/actions.ts +39 -30
  116. package/src/agent-comms.ts +54 -92
  117. package/src/approve.ts +91 -20
  118. package/src/ask.ts +99 -25
  119. package/src/browse.ts +627 -0
  120. package/src/capability-tiers.ts +5 -5
  121. package/src/client.ts +221 -0
  122. package/src/decide.ts +81 -35
  123. package/src/do.ts +98 -52
  124. package/src/error-escalation.ts +55 -67
  125. package/src/generate.ts +52 -18
  126. package/src/goals.ts +36 -27
  127. package/src/image.ts +816 -0
  128. package/src/index.ts +187 -2
  129. package/src/is.ts +59 -25
  130. package/src/kpis.ts +41 -36
  131. package/src/load-balancing.ts +132 -46
  132. package/src/logger.ts +93 -0
  133. package/src/notify.ts +78 -17
  134. package/src/role.ts +30 -20
  135. package/src/runtime.ts +796 -0
  136. package/src/team.ts +24 -19
  137. package/src/transports/email.ts +1160 -0
  138. package/src/transports/slack.ts +1320 -0
  139. package/src/transports.ts +58 -43
  140. package/src/types.ts +174 -46
  141. package/src/utils/id.ts +21 -0
  142. package/src/video.ts +906 -0
  143. package/src/worker.ts +1007 -0
  144. package/test/approve.test.ts +305 -0
  145. package/test/ask.test.ts +274 -0
  146. package/test/browse.test.ts +361 -0
  147. package/test/decide.test.ts +252 -0
  148. package/test/do.test.ts +144 -0
  149. package/test/error-logging.test.ts +357 -0
  150. package/test/generate.test.ts +319 -0
  151. package/test/image.test.ts +398 -0
  152. package/test/is.test.ts +287 -0
  153. package/test/load-balancing-safety.test.ts +404 -0
  154. package/test/notify.test.ts +434 -0
  155. package/test/primitives.test.ts +320 -0
  156. package/test/runtime-integration.test.ts +892 -0
  157. package/test/transports/crypto.test.ts +230 -0
  158. package/test/transports/email.test.ts +866 -0
  159. package/test/transports/id-generation.test.ts +91 -0
  160. package/test/transports/slack.test.ts +760 -0
  161. package/test/type-safety.test.ts +834 -0
  162. package/test/types.test.ts +60 -2
  163. package/test/video.test.ts +530 -0
  164. package/test/worker.test.ts +1433 -0
  165. package/tsconfig.json +4 -1
  166. package/vitest.config.ts +42 -0
  167. package/wrangler.jsonc +36 -0
  168. package/LICENSE +0 -21
  169. package/src/actions.js +0 -436
  170. package/src/approve.js +0 -234
  171. package/src/ask.js +0 -226
  172. package/src/decide.js +0 -244
  173. package/src/do.js +0 -227
  174. package/src/generate.js +0 -298
  175. package/src/goals.js +0 -205
  176. package/src/index.js +0 -68
  177. package/src/is.js +0 -317
  178. package/src/kpis.js +0 -270
  179. package/src/notify.js +0 -219
  180. package/src/role.js +0 -110
  181. package/src/team.js +0 -130
  182. package/src/transports.js +0 -357
  183. package/src/types.js +0 -71
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Browser automation functionality for digital workers
3
+ *
4
+ * IMPORTANT: Worker Routing vs Direct Browser Calls
5
+ * -------------------------------------------------
6
+ * This module provides worker-routed browser automation, enabling AI-assisted
7
+ * browser control with human fallback capabilities.
8
+ *
9
+ * - `digital-workers.browse()` - Routes browser automation tasks to Workers
10
+ * (AI Agents or Humans) based on capability matching and complexity.
11
+ *
12
+ * Use digital-workers.browse when you need:
13
+ * - AI-planned browser automation
14
+ * - Human-in-the-loop for complex interactions
15
+ * - Capability-based worker selection
16
+ * - Screenshot and data extraction with fallback
17
+ *
18
+ * @module
19
+ */
20
+ /**
21
+ * Viewport dimensions for browser automation
22
+ */
23
+ export interface Viewport {
24
+ width: number;
25
+ height: number;
26
+ }
27
+ /**
28
+ * Options for browser automation
29
+ */
30
+ export interface BrowseOptions {
31
+ /** URL to navigate to */
32
+ url: string;
33
+ /** Task or goal to accomplish in the browser */
34
+ task: string;
35
+ /** Maximum time to wait for task completion (ms) */
36
+ timeout?: number;
37
+ /** Run browser in headless mode */
38
+ headless?: boolean;
39
+ /** Browser viewport dimensions */
40
+ viewport?: Viewport;
41
+ /** Additional context for the task */
42
+ context?: Record<string, unknown>;
43
+ /** Wait for specific selector before starting */
44
+ waitFor?: string;
45
+ /** Cookies to set before navigation */
46
+ cookies?: Array<{
47
+ name: string;
48
+ value: string;
49
+ domain?: string;
50
+ }>;
51
+ /** User agent string */
52
+ userAgent?: string;
53
+ /** Enable human fallback for complex interactions */
54
+ humanFallback?: boolean;
55
+ /** Worker to route to (defaults to automatic selection) */
56
+ worker?: string;
57
+ }
58
+ /**
59
+ * Browser action types
60
+ */
61
+ export type BrowseActionType = 'navigate' | 'click' | 'type' | 'scroll' | 'wait' | 'screenshot' | 'extract';
62
+ /**
63
+ * Individual browser action record
64
+ */
65
+ export interface BrowseAction {
66
+ /** Type of action performed */
67
+ type: BrowseActionType;
68
+ /** Target selector or URL */
69
+ target?: string;
70
+ /** Value used in the action (text typed, scroll amount, etc.) */
71
+ value?: string;
72
+ /** Timestamp when action was performed */
73
+ timestamp?: Date;
74
+ /** Whether action succeeded */
75
+ success?: boolean;
76
+ /** Error message if action failed */
77
+ error?: string;
78
+ }
79
+ /**
80
+ * Result of browser automation
81
+ */
82
+ export interface BrowseResult {
83
+ /** Whether the overall task succeeded */
84
+ success: boolean;
85
+ /** Extracted data or task result */
86
+ data?: unknown;
87
+ /** Screenshot as base64 string (if requested) */
88
+ screenshot?: string;
89
+ /** List of actions performed */
90
+ actions: BrowseAction[];
91
+ /** Error message if task failed */
92
+ error?: string;
93
+ /** Duration of task execution (ms) */
94
+ duration?: number;
95
+ /** Final URL after navigation */
96
+ finalUrl?: string;
97
+ /** Page title */
98
+ title?: string;
99
+ /** Worker that executed the task */
100
+ executedBy?: string;
101
+ }
102
+ /**
103
+ * Options for click action
104
+ */
105
+ export interface ClickOptions {
106
+ /** Wait for navigation after click */
107
+ waitForNavigation?: boolean;
108
+ /** Click position offset from element center */
109
+ offset?: {
110
+ x: number;
111
+ y: number;
112
+ };
113
+ /** Number of clicks */
114
+ clickCount?: number;
115
+ /** Mouse button */
116
+ button?: 'left' | 'right' | 'middle';
117
+ }
118
+ /**
119
+ * Options for type action
120
+ */
121
+ export interface TypeOptions {
122
+ /** Clear existing text before typing */
123
+ clear?: boolean;
124
+ /** Delay between keystrokes (ms) */
125
+ delay?: number;
126
+ /** Press Enter after typing */
127
+ pressEnter?: boolean;
128
+ }
129
+ /**
130
+ * Options for scroll action
131
+ */
132
+ export interface ScrollOptions {
133
+ /** Scroll direction */
134
+ direction: 'up' | 'down' | 'left' | 'right';
135
+ /** Amount to scroll in pixels */
136
+ amount?: number;
137
+ /** Scroll to specific element */
138
+ toElement?: string;
139
+ /** Scroll smoothly */
140
+ smooth?: boolean;
141
+ }
142
+ /**
143
+ * Options for screenshot action
144
+ */
145
+ export interface ScreenshotOptions {
146
+ /** Capture full page or viewport only */
147
+ fullPage?: boolean;
148
+ /** Specific element to capture */
149
+ selector?: string;
150
+ /** Image format */
151
+ format?: 'png' | 'jpeg' | 'webp';
152
+ /** Image quality (0-100) for jpeg/webp */
153
+ quality?: number;
154
+ }
155
+ /**
156
+ * Options for extract action
157
+ */
158
+ export interface ExtractOptions {
159
+ /** Schema describing the data to extract */
160
+ schema?: Record<string, unknown>;
161
+ /** CSS selector to scope extraction */
162
+ selector?: string;
163
+ /** Extract multiple items */
164
+ multiple?: boolean;
165
+ /** Include raw HTML */
166
+ includeHtml?: boolean;
167
+ }
168
+ /**
169
+ * Execute browser automation by routing to an appropriate Worker (AI Agent or Human).
170
+ *
171
+ * This function uses AI to plan and execute browser actions to accomplish
172
+ * a given task. It supports human fallback for complex interactions that
173
+ * require human judgment.
174
+ *
175
+ * @param url - URL to navigate to
176
+ * @param task - Description of the task to accomplish
177
+ * @param options - Additional options for browser automation
178
+ * @returns Promise resolving to browse result with execution details
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * // Simple navigation and extraction
183
+ * const result = await browse('https://example.com', 'Find the contact email')
184
+ *
185
+ * if (result.success) {
186
+ * console.log('Email:', result.data)
187
+ * }
188
+ * ```
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * // Form submission
193
+ * const result = await browse('https://example.com/login', 'Log in with test credentials', {
194
+ * context: {
195
+ * username: 'testuser',
196
+ * password: 'testpass123',
197
+ * },
198
+ * timeout: 30000,
199
+ * })
200
+ * ```
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * // Complex interaction with human fallback
205
+ * const result = await browse('https://example.com/checkout', 'Complete the purchase', {
206
+ * humanFallback: true,
207
+ * timeout: 60000,
208
+ * })
209
+ * ```
210
+ */
211
+ export declare function browse(url: string, task: string, options?: Partial<BrowseOptions>): Promise<BrowseResult>;
212
+ export declare namespace browse {
213
+ var click: (url: string, selector: string, options?: ClickOptions) => Promise<BrowseResult>;
214
+ var type: (url: string, selector: string, text: string, options?: TypeOptions) => Promise<BrowseResult>;
215
+ var scroll: (url: string, direction: "up" | "down" | "left" | "right", amount?: number, options?: Partial<ScrollOptions>) => Promise<BrowseResult>;
216
+ var screenshot: (url: string, options?: ScreenshotOptions) => Promise<BrowseResult>;
217
+ var extract: (url: string, schema: Record<string, unknown>, options?: ExtractOptions) => Promise<BrowseResult>;
218
+ var waitFor: (url: string, selector: string, timeout?: number) => Promise<BrowseResult>;
219
+ var fill: (url: string, formData: Record<string, string>, submitSelector?: string) => Promise<BrowseResult>;
220
+ var crawl: (urls: string[], taskPerPage: string) => Promise<BrowseResult[]>;
221
+ }
222
+ export default browse;
223
+ //# sourceMappingURL=browse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../src/browse.ts"],"names":[],"mappings":"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"}
package/dist/browse.js ADDED
@@ -0,0 +1,392 @@
1
+ /**
2
+ * Browser automation functionality for digital workers
3
+ *
4
+ * IMPORTANT: Worker Routing vs Direct Browser Calls
5
+ * -------------------------------------------------
6
+ * This module provides worker-routed browser automation, enabling AI-assisted
7
+ * browser control with human fallback capabilities.
8
+ *
9
+ * - `digital-workers.browse()` - Routes browser automation tasks to Workers
10
+ * (AI Agents or Humans) based on capability matching and complexity.
11
+ *
12
+ * Use digital-workers.browse when you need:
13
+ * - AI-planned browser automation
14
+ * - Human-in-the-loop for complex interactions
15
+ * - Capability-based worker selection
16
+ * - Screenshot and data extraction with fallback
17
+ *
18
+ * @module
19
+ */
20
+ import { define } from 'ai-functions';
21
+ // ============================================================================
22
+ // Main Browse Function
23
+ // ============================================================================
24
+ /**
25
+ * Execute browser automation by routing to an appropriate Worker (AI Agent or Human).
26
+ *
27
+ * This function uses AI to plan and execute browser actions to accomplish
28
+ * a given task. It supports human fallback for complex interactions that
29
+ * require human judgment.
30
+ *
31
+ * @param url - URL to navigate to
32
+ * @param task - Description of the task to accomplish
33
+ * @param options - Additional options for browser automation
34
+ * @returns Promise resolving to browse result with execution details
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * // Simple navigation and extraction
39
+ * const result = await browse('https://example.com', 'Find the contact email')
40
+ *
41
+ * if (result.success) {
42
+ * console.log('Email:', result.data)
43
+ * }
44
+ * ```
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * // Form submission
49
+ * const result = await browse('https://example.com/login', 'Log in with test credentials', {
50
+ * context: {
51
+ * username: 'testuser',
52
+ * password: 'testpass123',
53
+ * },
54
+ * timeout: 30000,
55
+ * })
56
+ * ```
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * // Complex interaction with human fallback
61
+ * const result = await browse('https://example.com/checkout', 'Complete the purchase', {
62
+ * humanFallback: true,
63
+ * timeout: 60000,
64
+ * })
65
+ * ```
66
+ */
67
+ export async function browse(url, task, options = {}) {
68
+ const { timeout = 30000, headless = true, viewport = { width: 1280, height: 720 }, context, waitFor, humanFallback = false, } = options;
69
+ const startTime = Date.now();
70
+ const actions = [];
71
+ // Record initial navigation
72
+ actions.push({
73
+ type: 'navigate',
74
+ target: url,
75
+ timestamp: new Date(),
76
+ success: true,
77
+ });
78
+ // Use agentic function for browser automation planning
79
+ const browserFn = define.agentic({
80
+ name: 'browserAutomation',
81
+ description: 'Plan and execute browser actions to accomplish a task',
82
+ args: {
83
+ url: 'The URL to navigate to',
84
+ task: 'The task to accomplish',
85
+ contextInfo: 'Additional context and parameters',
86
+ viewportSize: 'Browser viewport dimensions',
87
+ },
88
+ returnType: {
89
+ success: 'Whether the task was completed successfully',
90
+ data: 'Extracted data or task result',
91
+ actions: ['List of browser actions taken'],
92
+ finalUrl: 'The final URL after all actions',
93
+ title: 'The page title',
94
+ error: 'Error message if task failed',
95
+ },
96
+ instructions: `You are a browser automation agent. Plan and execute browser actions to accomplish the task.
97
+
98
+ URL: ${url}
99
+ Task: ${task}
100
+ Viewport: ${viewport.width}x${viewport.height}
101
+ ${context ? `Context: ${JSON.stringify(context, null, 2)}` : ''}
102
+ ${waitFor ? `Wait for selector: ${waitFor}` : ''}
103
+
104
+ Available actions:
105
+ - navigate(url): Go to a URL
106
+ - click(selector): Click an element
107
+ - type(selector, text): Type text into an input
108
+ - scroll(direction, amount): Scroll the page
109
+ - wait(ms): Wait for a duration
110
+ - waitForSelector(selector): Wait for element to appear
111
+ - screenshot(): Take a screenshot
112
+ - extract(schema): Extract data from the page
113
+
114
+ Plan your actions step by step to accomplish the task efficiently.`,
115
+ maxIterations: 10,
116
+ tools: [], // Browser tools would be provided by the execution environment
117
+ });
118
+ try {
119
+ const response = (await Promise.race([
120
+ browserFn.call({
121
+ url,
122
+ task,
123
+ contextInfo: context ? JSON.stringify(context) : '',
124
+ viewportSize: `${viewport.width}x${viewport.height}`,
125
+ }),
126
+ timeout
127
+ ? new Promise((_, reject) => setTimeout(() => reject(new Error('Browser automation timeout')), timeout))
128
+ : new Promise(() => { }),
129
+ ]));
130
+ // Record actions from response
131
+ if (response.actions) {
132
+ actions.push(...response.actions.map((action) => {
133
+ const browseAction = {
134
+ type: action.type,
135
+ timestamp: new Date(),
136
+ success: true,
137
+ };
138
+ if (action.target !== undefined) {
139
+ browseAction.target = action.target;
140
+ }
141
+ if (action.value !== undefined) {
142
+ browseAction.value = action.value;
143
+ }
144
+ return browseAction;
145
+ }));
146
+ }
147
+ const duration = Date.now() - startTime;
148
+ const result = {
149
+ success: response.success,
150
+ actions,
151
+ duration,
152
+ finalUrl: response.finalUrl || url,
153
+ };
154
+ if (response.data !== undefined) {
155
+ result.data = response.data;
156
+ }
157
+ if (response.error !== undefined) {
158
+ result.error = response.error;
159
+ }
160
+ if (response.title !== undefined) {
161
+ result.title = response.title;
162
+ }
163
+ return result;
164
+ }
165
+ catch (error) {
166
+ const errorMessage = error instanceof Error ? error.message : String(error);
167
+ // If human fallback is enabled and AI fails, route to human
168
+ if (humanFallback) {
169
+ return {
170
+ success: false,
171
+ actions,
172
+ error: `AI automation failed, human fallback requested: ${errorMessage}`,
173
+ duration: Date.now() - startTime,
174
+ executedBy: 'pending-human-fallback',
175
+ };
176
+ }
177
+ return {
178
+ success: false,
179
+ actions,
180
+ error: errorMessage,
181
+ duration: Date.now() - startTime,
182
+ };
183
+ }
184
+ }
185
+ // ============================================================================
186
+ // Helper Methods
187
+ // ============================================================================
188
+ /**
189
+ * Click an element on a page
190
+ *
191
+ * @param url - URL of the page
192
+ * @param selector - CSS selector of the element to click
193
+ * @param options - Click options
194
+ * @returns Promise resolving to browse result
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * const result = await browse.click('https://example.com', '#submit-button')
199
+ * ```
200
+ */
201
+ browse.click = async (url, selector, options = {}) => {
202
+ const { waitForNavigation = false, clickCount = 1 } = options;
203
+ return browse(url, `Click the element matching selector "${selector}"`, {
204
+ context: {
205
+ action: 'click',
206
+ selector,
207
+ waitForNavigation,
208
+ clickCount,
209
+ },
210
+ });
211
+ };
212
+ /**
213
+ * Type text into an input element
214
+ *
215
+ * @param url - URL of the page
216
+ * @param selector - CSS selector of the input element
217
+ * @param text - Text to type
218
+ * @param options - Type options
219
+ * @returns Promise resolving to browse result
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * const result = await browse.type('https://example.com', '#search-input', 'hello world')
224
+ * ```
225
+ */
226
+ browse.type = async (url, selector, text, options = {}) => {
227
+ const { clear = false, delay = 0, pressEnter = false } = options;
228
+ return browse(url, `Type "${text}" into the element matching selector "${selector}"`, {
229
+ context: {
230
+ action: 'type',
231
+ selector,
232
+ text,
233
+ clear,
234
+ delay,
235
+ pressEnter,
236
+ },
237
+ });
238
+ };
239
+ /**
240
+ * Scroll the page
241
+ *
242
+ * @param url - URL of the page
243
+ * @param direction - Scroll direction
244
+ * @param amount - Amount to scroll in pixels (default: 500)
245
+ * @param options - Additional scroll options
246
+ * @returns Promise resolving to browse result
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const result = await browse.scroll('https://example.com', 'down', 500)
251
+ * ```
252
+ */
253
+ browse.scroll = async (url, direction, amount = 500, options = {}) => {
254
+ const { toElement, smooth = true } = options;
255
+ return browse(url, `Scroll ${direction} by ${amount} pixels`, {
256
+ context: {
257
+ action: 'scroll',
258
+ direction,
259
+ amount,
260
+ toElement,
261
+ smooth,
262
+ },
263
+ });
264
+ };
265
+ /**
266
+ * Take a screenshot of the page
267
+ *
268
+ * @param url - URL of the page
269
+ * @param options - Screenshot options
270
+ * @returns Promise resolving to browse result with screenshot
271
+ *
272
+ * @example
273
+ * ```ts
274
+ * const result = await browse.screenshot('https://example.com')
275
+ * if (result.screenshot) {
276
+ * // Save or process the base64 screenshot
277
+ * }
278
+ * ```
279
+ */
280
+ browse.screenshot = async (url, options = {}) => {
281
+ const { fullPage = false, selector, format = 'png', quality } = options;
282
+ return browse(url, 'Take a screenshot of the page', {
283
+ context: {
284
+ action: 'screenshot',
285
+ fullPage,
286
+ selector,
287
+ format,
288
+ quality,
289
+ },
290
+ });
291
+ };
292
+ /**
293
+ * Extract structured data from a page
294
+ *
295
+ * @param url - URL of the page
296
+ * @param schema - Schema describing the data to extract
297
+ * @param options - Extract options
298
+ * @returns Promise resolving to browse result with extracted data
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * const result = await browse.extract('https://example.com/products', {
303
+ * products: [{
304
+ * name: 'Product name',
305
+ * price: 'Product price as number',
306
+ * description: 'Product description',
307
+ * }],
308
+ * })
309
+ *
310
+ * if (result.success) {
311
+ * console.log('Products:', result.data)
312
+ * }
313
+ * ```
314
+ */
315
+ browse.extract = async (url, schema, options = {}) => {
316
+ const { selector, multiple = false, includeHtml = false } = options;
317
+ return browse(url, 'Extract structured data from the page according to the schema', {
318
+ context: {
319
+ action: 'extract',
320
+ schema,
321
+ selector,
322
+ multiple,
323
+ includeHtml,
324
+ },
325
+ });
326
+ };
327
+ /**
328
+ * Wait for an element to appear on the page
329
+ *
330
+ * @param url - URL of the page
331
+ * @param selector - CSS selector to wait for
332
+ * @param timeout - Maximum time to wait (ms)
333
+ * @returns Promise resolving to browse result
334
+ *
335
+ * @example
336
+ * ```ts
337
+ * const result = await browse.waitFor('https://example.com', '.loaded-content', 5000)
338
+ * ```
339
+ */
340
+ browse.waitFor = async (url, selector, timeout = 30000) => {
341
+ return browse(url, `Wait for element matching selector "${selector}" to appear`, {
342
+ waitFor: selector,
343
+ timeout,
344
+ });
345
+ };
346
+ /**
347
+ * Fill out a form with multiple fields
348
+ *
349
+ * @param url - URL of the page with the form
350
+ * @param formData - Object mapping selectors to values
351
+ * @param submitSelector - Optional selector for the submit button
352
+ * @returns Promise resolving to browse result
353
+ *
354
+ * @example
355
+ * ```ts
356
+ * const result = await browse.fill('https://example.com/contact', {
357
+ * '#name': 'John Doe',
358
+ * '#email': 'john@example.com',
359
+ * '#message': 'Hello!',
360
+ * }, '#submit')
361
+ * ```
362
+ */
363
+ browse.fill = async (url, formData, submitSelector) => {
364
+ return browse(url, 'Fill out the form with the provided data and submit if requested', {
365
+ context: {
366
+ action: 'fill',
367
+ formData,
368
+ submitSelector,
369
+ },
370
+ });
371
+ };
372
+ /**
373
+ * Navigate through multiple pages
374
+ *
375
+ * @param urls - Array of URLs to visit
376
+ * @param taskPerPage - Task to perform on each page
377
+ * @returns Promise resolving to array of browse results
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * const results = await browse.crawl(
382
+ * ['https://example.com/page1', 'https://example.com/page2'],
383
+ * 'Extract the page title'
384
+ * )
385
+ * ```
386
+ */
387
+ browse.crawl = async (urls, taskPerPage) => {
388
+ return Promise.all(urls.map((url) => browse(url, taskPerPage)));
389
+ };
390
+ // Export as default as well
391
+ export default browse;
392
+ //# sourceMappingURL=browse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browse.js","sourceRoot":"","sources":["../src/browse.ts"],"names":[],"mappings":"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"}
@@ -281,8 +281,8 @@ export function createCapabilityProfile(input) {
281
281
  tier,
282
282
  complexityRating,
283
283
  tools,
284
- description,
285
- constraints,
284
+ ...(description !== undefined && { description }),
285
+ ...(constraints !== undefined && { constraints }),
286
286
  };
287
287
  }
288
288
  // ============================================================================
@@ -346,7 +346,7 @@ export class TierRegistry {
346
346
  const result = [];
347
347
  for (const profile of this.profiles.values()) {
348
348
  const profileTools = new Set(profile.tools);
349
- const hasAllTools = requiredTools.every(tool => profileTools.has(tool));
349
+ const hasAllTools = requiredTools.every((tool) => profileTools.has(tool));
350
350
  if (hasAllTools) {
351
351
  result.push(profile);
352
352
  }