@elizaos/plugin-browser 1.0.3 → 2.0.0-alpha.2
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.
- package/LICENSE +1 -1
- package/README.md +75 -23
- package/dist/actions/click.d.ts +3 -0
- package/dist/actions/click.d.ts.map +1 -0
- package/dist/actions/click.js +98 -0
- package/dist/actions/click.js.map +1 -0
- package/dist/actions/extract.d.ts +3 -0
- package/dist/actions/extract.d.ts.map +1 -0
- package/dist/actions/extract.js +110 -0
- package/dist/actions/extract.js.map +1 -0
- package/dist/actions/index.d.ts +7 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +7 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/navigate.d.ts +3 -0
- package/dist/actions/navigate.d.ts.map +1 -0
- package/dist/actions/navigate.js +129 -0
- package/dist/actions/navigate.js.map +1 -0
- package/dist/actions/screenshot.d.ts +3 -0
- package/dist/actions/screenshot.d.ts.map +1 -0
- package/dist/actions/screenshot.js +107 -0
- package/dist/actions/screenshot.js.map +1 -0
- package/dist/actions/select.d.ts +3 -0
- package/dist/actions/select.d.ts.map +1 -0
- package/dist/actions/select.js +105 -0
- package/dist/actions/select.js.map +1 -0
- package/dist/actions/type.d.ts +3 -0
- package/dist/actions/type.d.ts.map +1 -0
- package/dist/actions/type.js +105 -0
- package/dist/actions/type.js.map +1 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -348
- package/dist/index.js.map +1 -1
- package/dist/providers/browser-state.d.ts +3 -0
- package/dist/providers/browser-state.d.ts.map +1 -0
- package/dist/providers/browser-state.js +47 -0
- package/dist/providers/browser-state.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/services/browser-service.d.ts +30 -0
- package/dist/services/browser-service.d.ts.map +1 -0
- package/dist/services/browser-service.js +164 -0
- package/dist/services/browser-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +4 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/process-manager.d.ts +15 -0
- package/dist/services/process-manager.d.ts.map +1 -0
- package/dist/services/process-manager.js +186 -0
- package/dist/services/process-manager.js.map +1 -0
- package/dist/services/websocket-client.d.ts +35 -0
- package/dist/services/websocket-client.d.ts.map +1 -0
- package/dist/services/websocket-client.js +219 -0
- package/dist/services/websocket-client.js.map +1 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/captcha.d.ts +33 -0
- package/dist/utils/captcha.d.ts.map +1 -0
- package/dist/utils/captcha.js +219 -0
- package/dist/utils/captcha.js.map +1 -0
- package/dist/utils/errors.d.ts +37 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +81 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/retry.d.ts +26 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +55 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/security.d.ts +27 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +138 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/url.d.ts +12 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +38 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +62 -43
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 Shaw Walters and elizaOS Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Browser Automation Plugin for ElizaOS (TypeScript)
|
|
2
2
|
|
|
3
|
-
Browser plugin
|
|
3
|
+
Browser automation plugin enabling AI agents to browse websites, interact with elements, and extract data.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
7
|
+
- **Navigation**: Navigate to URLs, go back/forward, refresh pages
|
|
8
|
+
- **AI-Powered Interactions**: Click, type, and select elements using natural language
|
|
9
|
+
- **Data Extraction**: Extract structured data from web pages
|
|
10
|
+
- **Screenshots**: Capture page screenshots
|
|
11
|
+
- **CAPTCHA Solving**: Automatic CAPTCHA solving (Turnstile, reCAPTCHA, hCaptcha)
|
|
12
|
+
- **Session Management**: Handle multiple browser sessions
|
|
13
|
+
- **Security**: URL validation, domain filtering, rate limiting
|
|
11
14
|
|
|
12
15
|
## Installation
|
|
13
16
|
|
|
@@ -15,33 +18,79 @@ Browser plugin for Eliza OS that provides web browsing and scraping capabilities
|
|
|
15
18
|
npm install @elizaos/plugin-browser
|
|
16
19
|
```
|
|
17
20
|
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Optional - for cloud browser
|
|
25
|
+
BROWSERBASE_API_KEY=your_api_key
|
|
26
|
+
BROWSERBASE_PROJECT_ID=your_project_id
|
|
27
|
+
|
|
28
|
+
# Optional - for AI-powered interactions
|
|
29
|
+
OPENAI_API_KEY=your_openai_key
|
|
30
|
+
ANTHROPIC_API_KEY=your_anthropic_key
|
|
31
|
+
|
|
32
|
+
# Optional - for CAPTCHA solving
|
|
33
|
+
CAPSOLVER_API_KEY=your_capsolver_key
|
|
34
|
+
|
|
35
|
+
# Browser settings
|
|
36
|
+
BROWSER_HEADLESS=true
|
|
37
|
+
BROWSER_ENABLED=true
|
|
38
|
+
```
|
|
39
|
+
|
|
18
40
|
## Usage
|
|
19
41
|
|
|
20
42
|
```typescript
|
|
21
43
|
import { browserPlugin } from '@elizaos/plugin-browser';
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
|
|
45
|
+
const agent = {
|
|
46
|
+
name: 'BrowserAgent',
|
|
25
47
|
plugins: [browserPlugin],
|
|
26
|
-
// ... other config
|
|
27
48
|
};
|
|
28
49
|
```
|
|
29
50
|
|
|
30
|
-
##
|
|
51
|
+
## Actions
|
|
52
|
+
|
|
53
|
+
| Action | Description | Examples |
|
|
54
|
+
| -------------------- | ------------------ | ----------------------------------- |
|
|
55
|
+
| `BROWSER_NAVIGATE` | Navigate to URL | "Go to google.com" |
|
|
56
|
+
| `BROWSER_BACK` | Go back in history | "Go back" |
|
|
57
|
+
| `BROWSER_FORWARD` | Go forward | "Go forward" |
|
|
58
|
+
| `BROWSER_REFRESH` | Refresh page | "Refresh the page" |
|
|
59
|
+
| `BROWSER_CLICK` | Click element | "Click the search button" |
|
|
60
|
+
| `BROWSER_TYPE` | Type text | "Type 'hello' in the search box" |
|
|
61
|
+
| `BROWSER_SELECT` | Select option | "Select 'US' from country dropdown" |
|
|
62
|
+
| `BROWSER_EXTRACT` | Extract data | "Extract the main heading" |
|
|
63
|
+
| `BROWSER_SCREENSHOT` | Take screenshot | "Take a screenshot" |
|
|
31
64
|
|
|
32
|
-
|
|
65
|
+
## Providers
|
|
33
66
|
|
|
34
|
-
|
|
67
|
+
| Provider | Description |
|
|
68
|
+
| --------------- | ----------------------------- |
|
|
69
|
+
| `BROWSER_STATE` | Current browser session state |
|
|
35
70
|
|
|
36
|
-
##
|
|
71
|
+
## API
|
|
37
72
|
|
|
38
73
|
### BrowserService
|
|
39
74
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
75
|
+
```typescript
|
|
76
|
+
class BrowserService extends Service {
|
|
77
|
+
async createSession(sessionId: string): Promise<BrowserSession>;
|
|
78
|
+
async getSession(sessionId: string): Promise<BrowserSession | undefined>;
|
|
79
|
+
async getCurrentSession(): Promise<BrowserSession | undefined>;
|
|
80
|
+
async destroySession(sessionId: string): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### BrowserSession
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
interface BrowserSession {
|
|
88
|
+
id: string;
|
|
89
|
+
createdAt: Date;
|
|
90
|
+
url?: string;
|
|
91
|
+
title?: string;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
45
94
|
|
|
46
95
|
## Development
|
|
47
96
|
|
|
@@ -49,16 +98,19 @@ Provides web browsing capabilities including:
|
|
|
49
98
|
# Install dependencies
|
|
50
99
|
npm install
|
|
51
100
|
|
|
52
|
-
# Build
|
|
101
|
+
# Build
|
|
53
102
|
npm run build
|
|
54
103
|
|
|
55
|
-
#
|
|
56
|
-
npm
|
|
104
|
+
# Run tests
|
|
105
|
+
npm test
|
|
57
106
|
|
|
58
|
-
#
|
|
59
|
-
npm run
|
|
107
|
+
# Type check
|
|
108
|
+
npm run typecheck
|
|
60
109
|
```
|
|
61
110
|
|
|
62
111
|
## License
|
|
63
112
|
|
|
64
113
|
MIT
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../src/actions/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAUvB,eAAO,MAAM,kBAAkB,EAAE,MA0HhC,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ServiceType } from "@elizaos/core";
|
|
2
|
+
import { ActionError, handleBrowserError, ServiceNotAvailableError, SessionError, } from "../utils/errors.js";
|
|
3
|
+
export const browserClickAction = {
|
|
4
|
+
name: "BROWSER_CLICK",
|
|
5
|
+
similes: ["CLICK_ELEMENT", "TAP", "PRESS_BUTTON"],
|
|
6
|
+
description: "Click on an element on the webpage",
|
|
7
|
+
validate: async (runtime, message, _state) => {
|
|
8
|
+
const browserEnabled = runtime.getSetting("ENABLE_BROWSER") === "true" ||
|
|
9
|
+
runtime.getSetting("BROWSER_ENABLED") === "true";
|
|
10
|
+
if (!browserEnabled) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
14
|
+
if (!service) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const text = message.content?.text?.toLowerCase() ?? "";
|
|
18
|
+
return text.includes("click") || text.includes("tap") || text.includes("press");
|
|
19
|
+
},
|
|
20
|
+
handler: async (runtime, message, _state, _options, callback, _responses) => {
|
|
21
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
22
|
+
if (!service) {
|
|
23
|
+
const error = new ServiceNotAvailableError();
|
|
24
|
+
handleBrowserError(error, callback, "click on element");
|
|
25
|
+
return {
|
|
26
|
+
text: "Browser service is not available",
|
|
27
|
+
success: false,
|
|
28
|
+
data: {
|
|
29
|
+
actionName: "BROWSER_CLICK",
|
|
30
|
+
error: "service_not_available",
|
|
31
|
+
},
|
|
32
|
+
values: {
|
|
33
|
+
success: false,
|
|
34
|
+
errorType: "service_not_available",
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const session = await service.getOrCreateSession();
|
|
39
|
+
if (!session) {
|
|
40
|
+
const error = new SessionError("No active browser session");
|
|
41
|
+
handleBrowserError(error, callback, "click on element");
|
|
42
|
+
return {
|
|
43
|
+
text: "No active browser session",
|
|
44
|
+
success: false,
|
|
45
|
+
data: {
|
|
46
|
+
actionName: "BROWSER_CLICK",
|
|
47
|
+
error: "no_session",
|
|
48
|
+
},
|
|
49
|
+
values: {
|
|
50
|
+
success: false,
|
|
51
|
+
errorType: "no_session",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const text = message.content?.text ?? "";
|
|
56
|
+
const match = text.match(/click (?:on |the )?(.+)$/i);
|
|
57
|
+
const description = match ? match[1] : "element";
|
|
58
|
+
const result = await service.getClient().click(session.id, description);
|
|
59
|
+
if (!result.success) {
|
|
60
|
+
throw new ActionError("click", description, new Error(result.error ?? "Click failed"));
|
|
61
|
+
}
|
|
62
|
+
const responseContent = {
|
|
63
|
+
text: `I've successfully clicked on "${description}"`,
|
|
64
|
+
actions: ["BROWSER_CLICK"],
|
|
65
|
+
source: message.content?.source ?? "action",
|
|
66
|
+
};
|
|
67
|
+
await callback?.(responseContent);
|
|
68
|
+
return {
|
|
69
|
+
text: responseContent.text ?? "",
|
|
70
|
+
success: true,
|
|
71
|
+
data: {
|
|
72
|
+
actionName: "BROWSER_CLICK",
|
|
73
|
+
element: description,
|
|
74
|
+
sessionId: session.id,
|
|
75
|
+
},
|
|
76
|
+
values: {
|
|
77
|
+
success: true,
|
|
78
|
+
element: description,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
examples: [
|
|
83
|
+
[
|
|
84
|
+
{
|
|
85
|
+
name: "{{user}}",
|
|
86
|
+
content: { text: "Click on the search button" },
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "{{agent}}",
|
|
90
|
+
content: {
|
|
91
|
+
text: "I've clicked on the search button.",
|
|
92
|
+
actions: ["BROWSER_CLICK"],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=click.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../src/actions/click.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Action,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { ServiceType } from \"@elizaos/core\";\nimport type { BrowserService } from \"../services/browser-service.js\";\nimport {\n ActionError,\n handleBrowserError,\n ServiceNotAvailableError,\n SessionError,\n} from \"../utils/errors.js\";\n\nexport const browserClickAction: Action = {\n name: \"BROWSER_CLICK\",\n similes: [\"CLICK_ELEMENT\", \"TAP\", \"PRESS_BUTTON\"],\n description: \"Click on an element on the webpage\",\n\n validate: async (runtime: IAgentRuntime, message: Memory, _state?: State): Promise<boolean> => {\n const browserEnabled =\n runtime.getSetting(\"ENABLE_BROWSER\") === \"true\" ||\n runtime.getSetting(\"BROWSER_ENABLED\") === \"true\";\n\n if (!browserEnabled) {\n return false;\n }\n\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n return false;\n }\n\n const text = message.content?.text?.toLowerCase() ?? \"\";\n return text.includes(\"click\") || text.includes(\"tap\") || text.includes(\"press\");\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ): Promise<ActionResult | undefined> => {\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n const error = new ServiceNotAvailableError();\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"click on element\"\n );\n return {\n text: \"Browser service is not available\",\n success: false,\n data: {\n actionName: \"BROWSER_CLICK\",\n error: \"service_not_available\",\n },\n values: {\n success: false,\n errorType: \"service_not_available\",\n },\n };\n }\n\n const session = await service.getOrCreateSession();\n if (!session) {\n const error = new SessionError(\"No active browser session\");\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"click on element\"\n );\n return {\n text: \"No active browser session\",\n success: false,\n data: {\n actionName: \"BROWSER_CLICK\",\n error: \"no_session\",\n },\n values: {\n success: false,\n errorType: \"no_session\",\n },\n };\n }\n\n const text = message.content?.text ?? \"\";\n const match = text.match(/click (?:on |the )?(.+)$/i);\n const description = match ? match[1] : \"element\";\n\n const result = await service.getClient().click(session.id, description);\n if (!result.success) {\n throw new ActionError(\"click\", description, new Error(result.error ?? \"Click failed\"));\n }\n\n const responseContent: Content = {\n text: `I've successfully clicked on \"${description}\"`,\n actions: [\"BROWSER_CLICK\"],\n source: message.content?.source ?? \"action\",\n };\n\n await callback?.(responseContent);\n\n return {\n text: responseContent.text ?? \"\",\n success: true,\n data: {\n actionName: \"BROWSER_CLICK\",\n element: description,\n sessionId: session.id,\n },\n values: {\n success: true,\n element: description,\n },\n };\n },\n\n examples: [\n [\n {\n name: \"{{user}}\",\n content: { text: \"Click on the search button\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I've clicked on the search button.\",\n actions: [\"BROWSER_CLICK\"],\n },\n },\n ],\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/actions/extract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAUvB,eAAO,MAAM,oBAAoB,EAAE,MAyIlC,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ServiceType } from "@elizaos/core";
|
|
2
|
+
import { ActionError, handleBrowserError, ServiceNotAvailableError, SessionError, } from "../utils/errors.js";
|
|
3
|
+
export const browserExtractAction = {
|
|
4
|
+
name: "BROWSER_EXTRACT",
|
|
5
|
+
similes: ["EXTRACT_DATA", "GET_TEXT", "SCRAPE"],
|
|
6
|
+
description: "Extract data from the webpage",
|
|
7
|
+
validate: async (runtime, message, _state) => {
|
|
8
|
+
const browserEnabled = runtime.getSetting("ENABLE_BROWSER") === "true" ||
|
|
9
|
+
runtime.getSetting("BROWSER_ENABLED") === "true";
|
|
10
|
+
if (!browserEnabled) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
14
|
+
if (!service) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const text = message.content?.text?.toLowerCase() ?? "";
|
|
18
|
+
return (text.includes("extract") ||
|
|
19
|
+
text.includes("get") ||
|
|
20
|
+
text.includes("scrape") ||
|
|
21
|
+
text.includes("find") ||
|
|
22
|
+
text.includes("read"));
|
|
23
|
+
},
|
|
24
|
+
handler: async (runtime, message, _state, _options, callback, _responses) => {
|
|
25
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
26
|
+
if (!service) {
|
|
27
|
+
const error = new ServiceNotAvailableError();
|
|
28
|
+
handleBrowserError(error, callback, "extract data");
|
|
29
|
+
return {
|
|
30
|
+
text: "Browser service is not available",
|
|
31
|
+
success: false,
|
|
32
|
+
data: {
|
|
33
|
+
actionName: "BROWSER_EXTRACT",
|
|
34
|
+
error: "service_not_available",
|
|
35
|
+
},
|
|
36
|
+
values: {
|
|
37
|
+
success: false,
|
|
38
|
+
errorType: "service_not_available",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const session = await service.getOrCreateSession();
|
|
43
|
+
if (!session) {
|
|
44
|
+
const error = new SessionError("No active browser session");
|
|
45
|
+
handleBrowserError(error, callback, "extract data");
|
|
46
|
+
return {
|
|
47
|
+
text: "No active browser session",
|
|
48
|
+
success: false,
|
|
49
|
+
data: {
|
|
50
|
+
actionName: "BROWSER_EXTRACT",
|
|
51
|
+
error: "no_session",
|
|
52
|
+
},
|
|
53
|
+
values: {
|
|
54
|
+
success: false,
|
|
55
|
+
errorType: "no_session",
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const text = message.content?.text ?? "";
|
|
60
|
+
const match = text.match(/(?:extract|get|find|scrape|read) (?:the )?(.+?)(?:\s+from|\s*$)/i);
|
|
61
|
+
const instruction = match ? match[1] : text;
|
|
62
|
+
const result = await service.getClient().extract(session.id, instruction);
|
|
63
|
+
if (!result.success) {
|
|
64
|
+
throw new ActionError("extract", "page", new Error(result.error ?? "Extraction failed"));
|
|
65
|
+
}
|
|
66
|
+
const extractedData = result.data;
|
|
67
|
+
const foundText = extractedData?.data ?? "No data found";
|
|
68
|
+
const found = extractedData?.found ?? false;
|
|
69
|
+
const responseContent = {
|
|
70
|
+
text: found
|
|
71
|
+
? `I found the ${instruction}: "${foundText}"`
|
|
72
|
+
: `I couldn't find the requested ${instruction} on the page.`,
|
|
73
|
+
actions: ["BROWSER_EXTRACT"],
|
|
74
|
+
source: message.content?.source ?? "action",
|
|
75
|
+
};
|
|
76
|
+
await callback?.(responseContent);
|
|
77
|
+
return {
|
|
78
|
+
text: responseContent.text ?? "",
|
|
79
|
+
success: true,
|
|
80
|
+
data: {
|
|
81
|
+
actionName: "BROWSER_EXTRACT",
|
|
82
|
+
instruction,
|
|
83
|
+
found,
|
|
84
|
+
extractedData: foundText,
|
|
85
|
+
sessionId: session.id,
|
|
86
|
+
},
|
|
87
|
+
values: {
|
|
88
|
+
success: true,
|
|
89
|
+
found,
|
|
90
|
+
data: foundText,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
examples: [
|
|
95
|
+
[
|
|
96
|
+
{
|
|
97
|
+
name: "{{user}}",
|
|
98
|
+
content: { text: "Extract the main heading from the page" },
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "{{agent}}",
|
|
102
|
+
content: {
|
|
103
|
+
text: 'I extracted the main heading: "Welcome to Our Website"',
|
|
104
|
+
actions: ["BROWSER_EXTRACT"],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/actions/extract.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Action,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { ServiceType } from \"@elizaos/core\";\nimport type { BrowserService } from \"../services/browser-service.js\";\nimport {\n ActionError,\n handleBrowserError,\n ServiceNotAvailableError,\n SessionError,\n} from \"../utils/errors.js\";\n\nexport const browserExtractAction: Action = {\n name: \"BROWSER_EXTRACT\",\n similes: [\"EXTRACT_DATA\", \"GET_TEXT\", \"SCRAPE\"],\n description: \"Extract data from the webpage\",\n\n validate: async (runtime: IAgentRuntime, message: Memory, _state?: State): Promise<boolean> => {\n const browserEnabled =\n runtime.getSetting(\"ENABLE_BROWSER\") === \"true\" ||\n runtime.getSetting(\"BROWSER_ENABLED\") === \"true\";\n\n if (!browserEnabled) {\n return false;\n }\n\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n return false;\n }\n\n const text = message.content?.text?.toLowerCase() ?? \"\";\n return (\n text.includes(\"extract\") ||\n text.includes(\"get\") ||\n text.includes(\"scrape\") ||\n text.includes(\"find\") ||\n text.includes(\"read\")\n );\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ): Promise<ActionResult | undefined> => {\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n const error = new ServiceNotAvailableError();\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"extract data\"\n );\n return {\n text: \"Browser service is not available\",\n success: false,\n data: {\n actionName: \"BROWSER_EXTRACT\",\n error: \"service_not_available\",\n },\n values: {\n success: false,\n errorType: \"service_not_available\",\n },\n };\n }\n\n const session = await service.getOrCreateSession();\n if (!session) {\n const error = new SessionError(\"No active browser session\");\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"extract data\"\n );\n return {\n text: \"No active browser session\",\n success: false,\n data: {\n actionName: \"BROWSER_EXTRACT\",\n error: \"no_session\",\n },\n values: {\n success: false,\n errorType: \"no_session\",\n },\n };\n }\n\n const text = message.content?.text ?? \"\";\n const match = text.match(/(?:extract|get|find|scrape|read) (?:the )?(.+?)(?:\\s+from|\\s*$)/i);\n const instruction = match ? match[1] : text;\n\n const result = await service.getClient().extract(session.id, instruction);\n if (!result.success) {\n throw new ActionError(\"extract\", \"page\", new Error(result.error ?? \"Extraction failed\"));\n }\n\n const extractedData = result.data as { data?: string; found?: boolean } | undefined;\n const foundText = extractedData?.data ?? \"No data found\";\n const found = extractedData?.found ?? false;\n\n const responseContent: Content = {\n text: found\n ? `I found the ${instruction}: \"${foundText}\"`\n : `I couldn't find the requested ${instruction} on the page.`,\n actions: [\"BROWSER_EXTRACT\"],\n source: message.content?.source ?? \"action\",\n };\n\n await callback?.(responseContent);\n\n return {\n text: responseContent.text ?? \"\",\n success: true,\n data: {\n actionName: \"BROWSER_EXTRACT\",\n instruction,\n found,\n extractedData: foundText,\n sessionId: session.id,\n },\n values: {\n success: true,\n found,\n data: foundText,\n },\n };\n },\n\n examples: [\n [\n {\n name: \"{{user}}\",\n content: { text: \"Extract the main heading from the page\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: 'I extracted the main heading: \"Welcome to Our Website\"',\n actions: [\"BROWSER_EXTRACT\"],\n },\n },\n ],\n ],\n};\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { browserClickAction } from "./click.js";
|
|
2
|
+
export { browserExtractAction } from "./extract.js";
|
|
3
|
+
export { browserNavigateAction } from "./navigate.js";
|
|
4
|
+
export { browserScreenshotAction } from "./screenshot.js";
|
|
5
|
+
export { browserSelectAction } from "./select.js";
|
|
6
|
+
export { browserTypeAction } from "./type.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { browserClickAction } from "./click.js";
|
|
2
|
+
export { browserExtractAction } from "./extract.js";
|
|
3
|
+
export { browserNavigateAction } from "./navigate.js";
|
|
4
|
+
export { browserScreenshotAction } from "./screenshot.js";
|
|
5
|
+
export { browserSelectAction } from "./select.js";
|
|
6
|
+
export { browserTypeAction } from "./type.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export { browserClickAction } from \"./click.js\";\nexport { browserExtractAction } from \"./extract.js\";\nexport { browserNavigateAction } from \"./navigate.js\";\nexport { browserScreenshotAction } from \"./screenshot.js\";\nexport { browserSelectAction } from \"./select.js\";\nexport { browserTypeAction } from \"./type.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAavB,eAAO,MAAM,qBAAqB,EAAE,MA6JnC,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ServiceType } from "@elizaos/core";
|
|
2
|
+
import { handleBrowserError, NoUrlFoundError, SecurityError, ServiceNotAvailableError, } from "../utils/errors.js";
|
|
3
|
+
import { DEFAULT_RETRY_CONFIGS, retryWithBackoff } from "../utils/retry.js";
|
|
4
|
+
import { defaultUrlValidator, validateSecureAction } from "../utils/security.js";
|
|
5
|
+
import { extractUrl } from "../utils/url.js";
|
|
6
|
+
export const browserNavigateAction = {
|
|
7
|
+
name: "BROWSER_NAVIGATE",
|
|
8
|
+
similes: ["GO_TO_URL", "OPEN_WEBSITE", "VISIT_PAGE", "NAVIGATE_TO"],
|
|
9
|
+
description: "Navigate the browser to a specified URL",
|
|
10
|
+
validate: async (runtime, message, _state) => {
|
|
11
|
+
const browserEnabled = runtime.getSetting("ENABLE_BROWSER") === "true" ||
|
|
12
|
+
runtime.getSetting("BROWSER_ENABLED") === "true";
|
|
13
|
+
if (!browserEnabled) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
17
|
+
if (!service) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const url = extractUrl(message.content.text ?? "");
|
|
21
|
+
return url !== null;
|
|
22
|
+
},
|
|
23
|
+
handler: async (runtime, message, _state, _options, callback, _responses) => {
|
|
24
|
+
const service = runtime.getService(ServiceType.BROWSER);
|
|
25
|
+
if (!service) {
|
|
26
|
+
const error = new ServiceNotAvailableError();
|
|
27
|
+
handleBrowserError(error, callback, "navigate to the requested page");
|
|
28
|
+
return {
|
|
29
|
+
text: "Browser service is not available",
|
|
30
|
+
success: false,
|
|
31
|
+
data: {
|
|
32
|
+
actionName: "BROWSER_NAVIGATE",
|
|
33
|
+
error: "service_not_available",
|
|
34
|
+
},
|
|
35
|
+
values: {
|
|
36
|
+
success: false,
|
|
37
|
+
errorType: "service_not_available",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const url = extractUrl(message.content.text ?? "");
|
|
42
|
+
if (!url) {
|
|
43
|
+
const error = new NoUrlFoundError();
|
|
44
|
+
handleBrowserError(error, callback, "navigate to a page");
|
|
45
|
+
return {
|
|
46
|
+
text: "I couldn't find a URL in your request. Please provide a valid URL to navigate to.",
|
|
47
|
+
success: false,
|
|
48
|
+
data: {
|
|
49
|
+
actionName: "BROWSER_NAVIGATE",
|
|
50
|
+
error: "no_url_found",
|
|
51
|
+
},
|
|
52
|
+
values: {
|
|
53
|
+
success: false,
|
|
54
|
+
errorType: "no_url_found",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
validateSecureAction(url, defaultUrlValidator);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof SecurityError) {
|
|
63
|
+
handleBrowserError(error, callback);
|
|
64
|
+
return {
|
|
65
|
+
text: "Security error: Cannot navigate to restricted URL",
|
|
66
|
+
success: false,
|
|
67
|
+
data: {
|
|
68
|
+
actionName: "BROWSER_NAVIGATE",
|
|
69
|
+
error: "security_error",
|
|
70
|
+
url,
|
|
71
|
+
},
|
|
72
|
+
values: {
|
|
73
|
+
success: false,
|
|
74
|
+
errorType: "security_error",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
let session = await service.getCurrentSession();
|
|
81
|
+
if (!session) {
|
|
82
|
+
const sessionId = `session-${Date.now()}`;
|
|
83
|
+
session = await service.createSession(sessionId);
|
|
84
|
+
}
|
|
85
|
+
const result = await retryWithBackoff(async () => {
|
|
86
|
+
const client = service.getClient();
|
|
87
|
+
return await client.navigate(session?.id, url);
|
|
88
|
+
}, DEFAULT_RETRY_CONFIGS.navigation, `navigate to ${url}`);
|
|
89
|
+
const responseContent = {
|
|
90
|
+
text: `I've navigated to ${url}. The page title is: "${result.title}"`,
|
|
91
|
+
actions: ["BROWSER_NAVIGATE"],
|
|
92
|
+
source: message.content.source,
|
|
93
|
+
};
|
|
94
|
+
await callback?.(responseContent);
|
|
95
|
+
return {
|
|
96
|
+
text: responseContent.text ?? "",
|
|
97
|
+
success: true,
|
|
98
|
+
data: {
|
|
99
|
+
actionName: "BROWSER_NAVIGATE",
|
|
100
|
+
url: result.url,
|
|
101
|
+
title: result.title,
|
|
102
|
+
sessionId: session.id,
|
|
103
|
+
},
|
|
104
|
+
values: {
|
|
105
|
+
success: true,
|
|
106
|
+
url: result.url,
|
|
107
|
+
pageTitle: result.title,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
examples: [
|
|
112
|
+
[
|
|
113
|
+
{
|
|
114
|
+
name: "{{user}}",
|
|
115
|
+
content: {
|
|
116
|
+
text: "Go to google.com",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "{{agent}}",
|
|
121
|
+
content: {
|
|
122
|
+
text: 'I\'ve navigated to https://google.com. The page title is: "Google"',
|
|
123
|
+
actions: ["BROWSER_NAVIGATE"],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=navigate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Action,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { ServiceType } from \"@elizaos/core\";\nimport type { BrowserService } from \"../services/browser-service.js\";\nimport {\n handleBrowserError,\n NoUrlFoundError,\n SecurityError,\n ServiceNotAvailableError,\n} from \"../utils/errors.js\";\nimport { DEFAULT_RETRY_CONFIGS, retryWithBackoff } from \"../utils/retry.js\";\nimport { defaultUrlValidator, validateSecureAction } from \"../utils/security.js\";\nimport { extractUrl } from \"../utils/url.js\";\n\nexport const browserNavigateAction: Action = {\n name: \"BROWSER_NAVIGATE\",\n similes: [\"GO_TO_URL\", \"OPEN_WEBSITE\", \"VISIT_PAGE\", \"NAVIGATE_TO\"],\n description: \"Navigate the browser to a specified URL\",\n\n validate: async (runtime: IAgentRuntime, message: Memory, _state?: State): Promise<boolean> => {\n const browserEnabled =\n runtime.getSetting(\"ENABLE_BROWSER\") === \"true\" ||\n runtime.getSetting(\"BROWSER_ENABLED\") === \"true\";\n\n if (!browserEnabled) {\n return false;\n }\n\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n return false;\n }\n\n const url = extractUrl(message.content.text ?? \"\");\n return url !== null;\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ): Promise<ActionResult | undefined> => {\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n if (!service) {\n const error = new ServiceNotAvailableError();\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"navigate to the requested page\"\n );\n return {\n text: \"Browser service is not available\",\n success: false,\n data: {\n actionName: \"BROWSER_NAVIGATE\",\n error: \"service_not_available\",\n },\n values: {\n success: false,\n errorType: \"service_not_available\",\n },\n };\n }\n\n const url = extractUrl(message.content.text ?? \"\");\n if (!url) {\n const error = new NoUrlFoundError();\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>,\n \"navigate to a page\"\n );\n return {\n text: \"I couldn't find a URL in your request. Please provide a valid URL to navigate to.\",\n success: false,\n data: {\n actionName: \"BROWSER_NAVIGATE\",\n error: \"no_url_found\",\n },\n values: {\n success: false,\n errorType: \"no_url_found\",\n },\n };\n }\n\n try {\n validateSecureAction(url, defaultUrlValidator);\n } catch (error) {\n if (error instanceof SecurityError) {\n handleBrowserError(\n error,\n callback as (content: { text: string; error?: boolean }) => Promise<unknown>\n );\n return {\n text: \"Security error: Cannot navigate to restricted URL\",\n success: false,\n data: {\n actionName: \"BROWSER_NAVIGATE\",\n error: \"security_error\",\n url,\n },\n values: {\n success: false,\n errorType: \"security_error\",\n },\n };\n }\n throw error;\n }\n\n let session = await service.getCurrentSession();\n if (!session) {\n const sessionId = `session-${Date.now()}`;\n session = await service.createSession(sessionId);\n }\n\n const result = await retryWithBackoff(\n async () => {\n const client = service.getClient();\n return await client.navigate(session?.id, url);\n },\n DEFAULT_RETRY_CONFIGS.navigation,\n `navigate to ${url}`\n );\n\n const responseContent: Content = {\n text: `I've navigated to ${url}. The page title is: \"${result.title}\"`,\n actions: [\"BROWSER_NAVIGATE\"],\n source: message.content.source,\n };\n\n await callback?.(responseContent);\n\n return {\n text: responseContent.text ?? \"\",\n success: true,\n data: {\n actionName: \"BROWSER_NAVIGATE\",\n url: result.url,\n title: result.title,\n sessionId: session.id,\n },\n values: {\n success: true,\n url: result.url,\n pageTitle: result.title,\n },\n };\n },\n\n examples: [\n [\n {\n name: \"{{user}}\",\n content: {\n text: \"Go to google.com\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: 'I\\'ve navigated to https://google.com. The page title is: \"Google\"',\n actions: [\"BROWSER_NAVIGATE\"],\n },\n },\n ],\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/actions/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAUvB,eAAO,MAAM,uBAAuB,EAAE,MA2IrC,CAAC"}
|