browser-use 0.2.0 → 0.3.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.
- package/README.md +295 -686
- package/dist/actor/element.d.ts +19 -0
- package/dist/actor/element.js +46 -0
- package/dist/actor/index.d.ts +4 -0
- package/dist/actor/index.js +4 -0
- package/dist/actor/mouse.d.ts +19 -0
- package/dist/actor/mouse.js +39 -0
- package/dist/actor/page.d.ts +29 -0
- package/dist/actor/page.js +88 -0
- package/dist/actor/utils.d.ts +4 -0
- package/dist/actor/utils.js +35 -0
- package/dist/agent/cloud-events.d.ts +18 -0
- package/dist/agent/cloud-events.js +65 -2
- package/dist/agent/gif.d.ts +1 -0
- package/dist/agent/gif.js +24 -2
- package/dist/agent/judge.d.ts +17 -0
- package/dist/agent/judge.js +197 -0
- package/dist/agent/message-manager/service.d.ts +12 -4
- package/dist/agent/message-manager/service.js +205 -39
- package/dist/agent/message-manager/utils.js +0 -1
- package/dist/agent/message-manager/views.d.ts +4 -0
- package/dist/agent/message-manager/views.js +11 -7
- package/dist/agent/prompts.d.ts +24 -3
- package/dist/agent/prompts.js +274 -59
- package/dist/agent/service.d.ts +99 -41
- package/dist/agent/service.js +2266 -472
- package/dist/agent/variable-detector.d.ts +12 -0
- package/dist/agent/variable-detector.js +211 -0
- package/dist/agent/views.d.ts +237 -18
- package/dist/agent/views.js +446 -33
- package/dist/browser/cloud/cloud.d.ts +20 -0
- package/dist/browser/cloud/cloud.js +129 -0
- package/dist/browser/cloud/index.d.ts +2 -0
- package/dist/browser/cloud/index.js +2 -0
- package/dist/browser/cloud/views.d.ts +41 -0
- package/dist/browser/cloud/views.js +35 -0
- package/dist/browser/events.d.ts +345 -0
- package/dist/browser/events.js +566 -0
- package/dist/browser/extensions.js +17 -17
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +4 -0
- package/dist/browser/profile.d.ts +8 -2
- package/dist/browser/profile.js +79 -12
- package/dist/browser/session-manager.d.ts +85 -0
- package/dist/browser/session-manager.js +208 -0
- package/dist/browser/session.d.ts +100 -8
- package/dist/browser/session.js +1097 -58
- package/dist/browser/types.d.ts +0 -2
- package/dist/browser/views.d.ts +39 -0
- package/dist/browser/views.js +32 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
- package/dist/browser/watchdogs/base.d.ts +21 -0
- package/dist/browser/watchdogs/base.js +81 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
- package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
- package/dist/browser/watchdogs/crash-watchdog.js +296 -0
- package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
- package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
- package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/dom-watchdog.js +31 -0
- package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
- package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
- package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
- package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
- package/dist/browser/watchdogs/index.d.ts +15 -0
- package/dist/browser/watchdogs/index.js +15 -0
- package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
- package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
- package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
- package/dist/browser/watchdogs/popups-watchdog.js +77 -0
- package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
- package/dist/browser/watchdogs/recording-watchdog.js +249 -0
- package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
- package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
- package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/security-watchdog.js +84 -0
- package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
- package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
- package/dist/cli.d.ts +7 -2
- package/dist/cli.js +182 -25
- package/dist/code-use/formatting.d.ts +3 -0
- package/dist/code-use/formatting.js +18 -0
- package/dist/code-use/index.d.ts +6 -0
- package/dist/code-use/index.js +6 -0
- package/dist/code-use/namespace.d.ts +5 -0
- package/dist/code-use/namespace.js +81 -0
- package/dist/code-use/notebook-export.d.ts +3 -0
- package/dist/code-use/notebook-export.js +56 -0
- package/dist/code-use/service.d.ts +24 -0
- package/dist/code-use/service.js +104 -0
- package/dist/code-use/utils.d.ts +4 -0
- package/dist/code-use/utils.js +98 -0
- package/dist/code-use/views.d.ts +108 -0
- package/dist/code-use/views.js +165 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +69 -3
- package/dist/controller/registry/service.d.ts +10 -1
- package/dist/controller/registry/service.js +266 -10
- package/dist/controller/registry/views.d.ts +4 -1
- package/dist/controller/registry/views.js +25 -2
- package/dist/controller/service.d.ts +10 -1
- package/dist/controller/service.js +1807 -268
- package/dist/controller/views.d.ts +78 -155
- package/dist/controller/views.js +61 -12
- package/dist/dom/history-tree-processor/service.d.ts +5 -0
- package/dist/dom/history-tree-processor/service.js +169 -14
- package/dist/dom/history-tree-processor/view.d.ts +7 -1
- package/dist/dom/history-tree-processor/view.js +10 -1
- package/dist/dom/markdown-extractor.d.ts +37 -0
- package/dist/dom/markdown-extractor.js +345 -0
- package/dist/dom/service.d.ts +3 -1
- package/dist/dom/service.js +76 -0
- package/dist/dom/views.d.ts +1 -0
- package/dist/dom/views.js +45 -0
- package/dist/event-bus.d.ts +107 -7
- package/dist/event-bus.js +313 -10
- package/dist/exceptions.d.ts +0 -3
- package/dist/exceptions.js +0 -7
- package/dist/filesystem/file-system.d.ts +18 -0
- package/dist/filesystem/file-system.js +503 -42
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/integrations/gmail/actions.d.ts +3 -3
- package/dist/integrations/gmail/actions.js +4 -4
- package/dist/llm/anthropic/chat.d.ts +18 -1
- package/dist/llm/anthropic/chat.js +123 -55
- package/dist/llm/anthropic/serializer.d.ts +2 -0
- package/dist/llm/anthropic/serializer.js +81 -9
- package/dist/llm/aws/chat-anthropic.d.ts +17 -0
- package/dist/llm/aws/chat-anthropic.js +126 -26
- package/dist/llm/aws/chat-bedrock.d.ts +28 -1
- package/dist/llm/aws/chat-bedrock.js +161 -34
- package/dist/llm/aws/serializer.d.ts +13 -1
- package/dist/llm/aws/serializer.js +56 -17
- package/dist/llm/azure/chat.d.ts +53 -2
- package/dist/llm/azure/chat.js +366 -54
- package/dist/llm/base.d.ts +2 -0
- package/dist/llm/browser-use/chat.d.ts +40 -0
- package/dist/llm/browser-use/chat.js +305 -0
- package/dist/llm/browser-use/index.d.ts +1 -0
- package/dist/llm/browser-use/index.js +1 -0
- package/dist/llm/cerebras/chat.d.ts +39 -0
- package/dist/llm/cerebras/chat.js +178 -0
- package/dist/llm/cerebras/index.d.ts +2 -0
- package/dist/llm/cerebras/index.js +2 -0
- package/dist/llm/cerebras/serializer.d.ts +7 -0
- package/dist/llm/cerebras/serializer.js +82 -0
- package/dist/llm/deepseek/chat.d.ts +19 -2
- package/dist/llm/deepseek/chat.js +138 -25
- package/dist/llm/google/chat.d.ts +46 -2
- package/dist/llm/google/chat.js +267 -64
- package/dist/llm/google/serializer.d.ts +9 -1
- package/dist/llm/google/serializer.js +141 -34
- package/dist/llm/groq/chat.d.ts +21 -2
- package/dist/llm/groq/chat.js +125 -26
- package/dist/llm/groq/parser.js +3 -1
- package/dist/llm/mistral/chat.d.ts +43 -0
- package/dist/llm/mistral/chat.js +154 -0
- package/dist/llm/mistral/index.d.ts +2 -0
- package/dist/llm/mistral/index.js +2 -0
- package/dist/llm/mistral/schema.d.ts +8 -0
- package/dist/llm/mistral/schema.js +27 -0
- package/dist/llm/models.d.ts +2 -0
- package/dist/llm/models.js +317 -0
- package/dist/llm/ollama/chat.d.ts +13 -1
- package/dist/llm/ollama/chat.js +110 -19
- package/dist/llm/ollama/serializer.d.ts +1 -0
- package/dist/llm/ollama/serializer.js +34 -12
- package/dist/llm/openai/chat.d.ts +16 -0
- package/dist/llm/openai/chat.js +94 -44
- package/dist/llm/openai/like.d.ts +5 -3
- package/dist/llm/openai/like.js +7 -3
- package/dist/llm/openai/responses-serializer.d.ts +18 -0
- package/dist/llm/openai/responses-serializer.js +72 -0
- package/dist/llm/openrouter/chat.d.ts +28 -2
- package/dist/llm/openrouter/chat.js +115 -29
- package/dist/llm/schema.d.ts +11 -1
- package/dist/llm/schema.js +81 -1
- package/dist/llm/vercel/chat.d.ts +50 -0
- package/dist/llm/vercel/chat.js +276 -0
- package/dist/llm/vercel/index.d.ts +1 -0
- package/dist/llm/vercel/index.js +1 -0
- package/dist/llm/vercel/serializer.d.ts +5 -0
- package/dist/llm/vercel/serializer.js +7 -0
- package/dist/llm/views.d.ts +2 -1
- package/dist/llm/views.js +3 -1
- package/dist/logging-config.d.ts +2 -0
- package/dist/logging-config.js +82 -29
- package/dist/mcp/client.d.ts +10 -5
- package/dist/mcp/client.js +14 -9
- package/dist/mcp/controller.d.ts +42 -3
- package/dist/mcp/controller.js +56 -31
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.js +255 -52
- package/dist/observability.js +10 -4
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.js +2 -0
- package/dist/sandbox/sandbox.d.ts +19 -0
- package/dist/sandbox/sandbox.js +140 -0
- package/dist/sandbox/views.d.ts +67 -0
- package/dist/sandbox/views.js +121 -0
- package/dist/skill-cli/index.d.ts +3 -0
- package/dist/skill-cli/index.js +3 -0
- package/dist/skill-cli/protocol.d.ts +30 -0
- package/dist/skill-cli/protocol.js +48 -0
- package/dist/skill-cli/server.d.ts +11 -0
- package/dist/skill-cli/server.js +85 -0
- package/dist/skill-cli/sessions.d.ts +24 -0
- package/dist/skill-cli/sessions.js +47 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/service.d.ts +27 -0
- package/dist/skills/service.js +266 -0
- package/dist/skills/utils.d.ts +6 -0
- package/dist/skills/utils.js +53 -0
- package/dist/skills/views.d.ts +40 -0
- package/dist/skills/views.js +10 -0
- package/dist/sync/auth.js +8 -3
- package/dist/sync/service.d.ts +6 -6
- package/dist/sync/service.js +54 -89
- package/dist/telemetry/views.d.ts +20 -6
- package/dist/telemetry/views.js +23 -5
- package/dist/tokens/custom-pricing.d.ts +2 -0
- package/dist/tokens/custom-pricing.js +22 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/mappings.d.ts +1 -0
- package/dist/tokens/mappings.js +3 -0
- package/dist/tokens/service.js +27 -8
- package/dist/tools/extraction/index.d.ts +2 -0
- package/dist/tools/extraction/index.js +2 -0
- package/dist/tools/extraction/schema-utils.d.ts +6 -0
- package/dist/tools/extraction/schema-utils.js +237 -0
- package/dist/tools/extraction/views.d.ts +7 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/registry/index.d.ts +2 -0
- package/dist/tools/registry/index.js +2 -0
- package/dist/tools/registry/service.d.ts +1 -0
- package/dist/tools/registry/service.js +1 -0
- package/dist/tools/registry/views.d.ts +1 -0
- package/dist/tools/registry/views.js +1 -0
- package/dist/tools/service.d.ts +2 -0
- package/dist/tools/service.js +1 -0
- package/dist/tools/utils.d.ts +2 -0
- package/dist/tools/utils.js +57 -0
- package/dist/tools/views.d.ts +1 -0
- package/dist/tools/views.js +1 -0
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +70 -3
- package/package.json +87 -26
- package/dist/dom/playground/process-dom.js +0 -5
- package/dist/dom/playground/test-accessibility.d.ts +0 -44
- package/dist/dom/playground/test-accessibility.js +0 -111
- /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
|
@@ -7,46 +7,60 @@ export interface AgentTelemetryPayload {
|
|
|
7
7
|
task: string;
|
|
8
8
|
model: string;
|
|
9
9
|
model_provider: string;
|
|
10
|
-
planner_llm: string | null;
|
|
11
10
|
max_steps: number;
|
|
12
11
|
max_actions_per_step: number;
|
|
13
|
-
use_vision: boolean;
|
|
14
|
-
use_validation: boolean;
|
|
12
|
+
use_vision: boolean | 'auto';
|
|
15
13
|
version: string;
|
|
16
14
|
source: string;
|
|
17
15
|
cdp_url: string | null;
|
|
16
|
+
agent_type: string | null;
|
|
18
17
|
action_errors: BaseSequence;
|
|
19
18
|
action_history: Array<Array<Record<string, unknown>> | null> | undefined;
|
|
20
19
|
urls_visited: BaseSequence;
|
|
21
20
|
steps: number;
|
|
22
21
|
total_input_tokens: number;
|
|
22
|
+
total_output_tokens: number;
|
|
23
|
+
prompt_cached_tokens: number;
|
|
24
|
+
total_tokens: number;
|
|
23
25
|
total_duration_seconds: number;
|
|
24
26
|
success: boolean | null;
|
|
25
27
|
final_result_response: string | null;
|
|
26
28
|
error_message: string | null;
|
|
29
|
+
judge_verdict?: boolean | null;
|
|
30
|
+
judge_reasoning?: string | null;
|
|
31
|
+
judge_failure_reason?: string | null;
|
|
32
|
+
judge_reached_captcha?: boolean | null;
|
|
33
|
+
judge_impossible_task?: boolean | null;
|
|
27
34
|
}
|
|
28
35
|
export declare class AgentTelemetryEvent extends BaseTelemetryEvent implements AgentTelemetryPayload {
|
|
29
36
|
name: string;
|
|
30
37
|
task: string;
|
|
31
38
|
model: string;
|
|
32
39
|
model_provider: string;
|
|
33
|
-
planner_llm: string | null;
|
|
34
40
|
max_steps: number;
|
|
35
41
|
max_actions_per_step: number;
|
|
36
|
-
use_vision: boolean;
|
|
37
|
-
use_validation: boolean;
|
|
42
|
+
use_vision: boolean | 'auto';
|
|
38
43
|
version: string;
|
|
39
44
|
source: string;
|
|
40
45
|
cdp_url: string | null;
|
|
46
|
+
agent_type: string | null;
|
|
41
47
|
action_errors: BaseSequence;
|
|
42
48
|
action_history: Array<Array<Record<string, unknown>> | null> | undefined;
|
|
43
49
|
urls_visited: BaseSequence;
|
|
44
50
|
steps: number;
|
|
45
51
|
total_input_tokens: number;
|
|
52
|
+
total_output_tokens: number;
|
|
53
|
+
prompt_cached_tokens: number;
|
|
54
|
+
total_tokens: number;
|
|
46
55
|
total_duration_seconds: number;
|
|
47
56
|
success: boolean | null;
|
|
48
57
|
final_result_response: string | null;
|
|
49
58
|
error_message: string | null;
|
|
59
|
+
judge_verdict: boolean | null;
|
|
60
|
+
judge_reasoning: string | null;
|
|
61
|
+
judge_failure_reason: string | null;
|
|
62
|
+
judge_reached_captcha: boolean | null;
|
|
63
|
+
judge_impossible_task: boolean | null;
|
|
50
64
|
constructor(payload: AgentTelemetryPayload);
|
|
51
65
|
}
|
|
52
66
|
export interface MCPClientTelemetryPayload {
|
package/dist/telemetry/views.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { is_running_in_docker } from '../config.js';
|
|
1
2
|
export class BaseTelemetryEvent {
|
|
2
3
|
properties() {
|
|
3
4
|
const entries = Object.entries(this).filter(([key]) => key !== 'name');
|
|
4
|
-
return
|
|
5
|
+
return {
|
|
6
|
+
...Object.fromEntries(entries),
|
|
7
|
+
is_docker: is_running_in_docker(),
|
|
8
|
+
};
|
|
5
9
|
}
|
|
6
10
|
}
|
|
7
11
|
export class AgentTelemetryEvent extends BaseTelemetryEvent {
|
|
@@ -9,45 +13,59 @@ export class AgentTelemetryEvent extends BaseTelemetryEvent {
|
|
|
9
13
|
task;
|
|
10
14
|
model;
|
|
11
15
|
model_provider;
|
|
12
|
-
planner_llm;
|
|
13
16
|
max_steps;
|
|
14
17
|
max_actions_per_step;
|
|
15
18
|
use_vision;
|
|
16
|
-
use_validation;
|
|
17
19
|
version;
|
|
18
20
|
source;
|
|
19
21
|
cdp_url;
|
|
22
|
+
agent_type;
|
|
20
23
|
action_errors;
|
|
21
24
|
action_history;
|
|
22
25
|
urls_visited;
|
|
23
26
|
steps;
|
|
24
27
|
total_input_tokens;
|
|
28
|
+
total_output_tokens;
|
|
29
|
+
prompt_cached_tokens;
|
|
30
|
+
total_tokens;
|
|
25
31
|
total_duration_seconds;
|
|
26
32
|
success;
|
|
27
33
|
final_result_response;
|
|
28
34
|
error_message;
|
|
35
|
+
judge_verdict;
|
|
36
|
+
judge_reasoning;
|
|
37
|
+
judge_failure_reason;
|
|
38
|
+
judge_reached_captcha;
|
|
39
|
+
judge_impossible_task;
|
|
29
40
|
constructor(payload) {
|
|
30
41
|
super();
|
|
31
42
|
this.task = payload.task;
|
|
32
43
|
this.model = payload.model;
|
|
33
44
|
this.model_provider = payload.model_provider;
|
|
34
|
-
this.planner_llm = payload.planner_llm;
|
|
35
45
|
this.max_steps = payload.max_steps;
|
|
36
46
|
this.max_actions_per_step = payload.max_actions_per_step;
|
|
37
47
|
this.use_vision = payload.use_vision;
|
|
38
|
-
this.use_validation = payload.use_validation;
|
|
39
48
|
this.version = payload.version;
|
|
40
49
|
this.source = payload.source;
|
|
41
50
|
this.cdp_url = payload.cdp_url;
|
|
51
|
+
this.agent_type = payload.agent_type;
|
|
42
52
|
this.action_errors = payload.action_errors;
|
|
43
53
|
this.action_history = payload.action_history;
|
|
44
54
|
this.urls_visited = payload.urls_visited;
|
|
45
55
|
this.steps = payload.steps;
|
|
46
56
|
this.total_input_tokens = payload.total_input_tokens;
|
|
57
|
+
this.total_output_tokens = payload.total_output_tokens;
|
|
58
|
+
this.prompt_cached_tokens = payload.prompt_cached_tokens;
|
|
59
|
+
this.total_tokens = payload.total_tokens;
|
|
47
60
|
this.total_duration_seconds = payload.total_duration_seconds;
|
|
48
61
|
this.success = payload.success;
|
|
49
62
|
this.final_result_response = payload.final_result_response;
|
|
50
63
|
this.error_message = payload.error_message;
|
|
64
|
+
this.judge_verdict = payload.judge_verdict ?? null;
|
|
65
|
+
this.judge_reasoning = payload.judge_reasoning ?? null;
|
|
66
|
+
this.judge_failure_reason = payload.judge_failure_reason ?? null;
|
|
67
|
+
this.judge_reached_captcha = payload.judge_reached_captcha ?? null;
|
|
68
|
+
this.judge_impossible_task = payload.judge_impossible_task ?? null;
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
export class MCPClientTelemetryEvent extends BaseTelemetryEvent {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const CUSTOM_MODEL_PRICING = {
|
|
2
|
+
'bu-1-0': {
|
|
3
|
+
input_cost_per_token: 0.2 / 1_000_000,
|
|
4
|
+
output_cost_per_token: 2.0 / 1_000_000,
|
|
5
|
+
cache_read_input_token_cost: 0.02 / 1_000_000,
|
|
6
|
+
cache_creation_input_token_cost: null,
|
|
7
|
+
max_tokens: null,
|
|
8
|
+
max_input_tokens: null,
|
|
9
|
+
max_output_tokens: null,
|
|
10
|
+
},
|
|
11
|
+
'bu-2-0': {
|
|
12
|
+
input_cost_per_token: 0.6 / 1_000_000,
|
|
13
|
+
output_cost_per_token: 3.5 / 1_000_000,
|
|
14
|
+
cache_read_input_token_cost: 0.06 / 1_000_000,
|
|
15
|
+
cache_creation_input_token_cost: null,
|
|
16
|
+
max_tokens: null,
|
|
17
|
+
max_input_tokens: null,
|
|
18
|
+
max_output_tokens: null,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
CUSTOM_MODEL_PRICING['bu-latest'] = CUSTOM_MODEL_PRICING['bu-1-0'];
|
|
22
|
+
CUSTOM_MODEL_PRICING.smart = CUSTOM_MODEL_PRICING['bu-1-0'];
|
package/dist/tokens/index.d.ts
CHANGED
package/dist/tokens/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MODEL_TO_LITELLM: Record<string, string>;
|
package/dist/tokens/service.js
CHANGED
|
@@ -4,6 +4,9 @@ import { encode } from 'gpt-tokenizer';
|
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import { CONFIG } from '../config.js';
|
|
6
6
|
import { createLogger } from '../logging-config.js';
|
|
7
|
+
import { create_task_with_error_handling } from '../utils.js';
|
|
8
|
+
import { CUSTOM_MODEL_PRICING } from './custom-pricing.js';
|
|
9
|
+
import { MODEL_TO_LITELLM } from './mappings.js';
|
|
7
10
|
const logger = createLogger('browser_use.tokens');
|
|
8
11
|
const costLogger = createLogger('browser_use.tokens.cost');
|
|
9
12
|
const PRICING_URL = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';
|
|
@@ -66,7 +69,7 @@ export class TokenCost {
|
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
catch (error) {
|
|
69
|
-
logger.
|
|
72
|
+
logger.debug(`Failed to load token pricing cache: ${error.message}`);
|
|
70
73
|
}
|
|
71
74
|
await this.fetchAndCachePricing();
|
|
72
75
|
}
|
|
@@ -125,7 +128,7 @@ export class TokenCost {
|
|
|
125
128
|
await fs.promises.writeFile(path.join(this.cacheDir, fileName), JSON.stringify(cached, null, 2));
|
|
126
129
|
}
|
|
127
130
|
catch (error) {
|
|
128
|
-
logger.
|
|
131
|
+
logger.debug(`Failed to fetch LiteLLM pricing: ${error.message}`);
|
|
129
132
|
this.pricingData = this.pricingData ?? {};
|
|
130
133
|
}
|
|
131
134
|
}
|
|
@@ -150,7 +153,10 @@ export class TokenCost {
|
|
|
150
153
|
const result = await original(...args);
|
|
151
154
|
if (result?.usage) {
|
|
152
155
|
const usageEntry = this.addUsage(llm.model, result.usage);
|
|
153
|
-
this.logUsage(llm.model, usageEntry)
|
|
156
|
+
create_task_with_error_handling(this.logUsage(llm.model, usageEntry), {
|
|
157
|
+
name: 'log_token_usage',
|
|
158
|
+
suppress_exceptions: true,
|
|
159
|
+
});
|
|
154
160
|
}
|
|
155
161
|
return result;
|
|
156
162
|
});
|
|
@@ -167,7 +173,7 @@ export class TokenCost {
|
|
|
167
173
|
const completionSection = this.includeCost && cost && cost.completion_cost > 0
|
|
168
174
|
? `📤 ${ansi.green}${completionTokensFmt} ($${cost.completion_cost.toFixed(4)})${ansi.reset}`
|
|
169
175
|
: `📤 ${ansi.green}${completionTokensFmt}${ansi.reset}`;
|
|
170
|
-
costLogger.
|
|
176
|
+
costLogger.debug(`🧠 ${ansi.cyan}${model}${ansi.reset} | ${inputPart} | ${completionSection}`);
|
|
171
177
|
}
|
|
172
178
|
buildInputDisplay(usage, cost) {
|
|
173
179
|
const parts = [];
|
|
@@ -244,11 +250,25 @@ export class TokenCost {
|
|
|
244
250
|
};
|
|
245
251
|
}
|
|
246
252
|
async getModelPricing(modelName) {
|
|
253
|
+
const customPricing = CUSTOM_MODEL_PRICING[modelName];
|
|
254
|
+
if (customPricing) {
|
|
255
|
+
return {
|
|
256
|
+
model: modelName,
|
|
257
|
+
input_cost_per_token: customPricing.input_cost_per_token ?? null,
|
|
258
|
+
output_cost_per_token: customPricing.output_cost_per_token ?? null,
|
|
259
|
+
cache_read_input_token_cost: customPricing.cache_read_input_token_cost ?? null,
|
|
260
|
+
cache_creation_input_token_cost: customPricing.cache_creation_input_token_cost ?? null,
|
|
261
|
+
max_tokens: customPricing.max_tokens ?? null,
|
|
262
|
+
max_input_tokens: customPricing.max_input_tokens ?? null,
|
|
263
|
+
max_output_tokens: customPricing.max_output_tokens ?? null,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
247
266
|
await this.ensurePricingLoaded();
|
|
248
267
|
if (!this.pricingData) {
|
|
249
268
|
return null;
|
|
250
269
|
}
|
|
251
|
-
const
|
|
270
|
+
const litellmModelName = MODEL_TO_LITELLM[modelName] ?? modelName;
|
|
271
|
+
const pricing = this.pricingData[litellmModelName];
|
|
252
272
|
if (!pricing) {
|
|
253
273
|
return null;
|
|
254
274
|
}
|
|
@@ -367,9 +387,8 @@ export class TokenCost {
|
|
|
367
387
|
const completionCostPart = this.includeCost && summary.total_completion_cost > 0
|
|
368
388
|
? ` ($${summary.total_completion_cost.toFixed(4)})`
|
|
369
389
|
: '';
|
|
370
|
-
costLogger.
|
|
390
|
+
costLogger.debug(`💲 ${ansi.bold}Total Usage Summary${ansi.reset}: ${ansi.blue}${totalTokens} tokens${ansi.reset}${totalCostPart} | ` +
|
|
371
391
|
`⬅️ ${ansi.yellow}${promptTokens}${promptCostPart}${ansi.reset} | ➡️ ${ansi.green}${completionTokens}${completionCostPart}${ansi.reset}`);
|
|
372
|
-
costLogger.info(`📊 ${ansi.bold}Per-Model Usage Breakdown${ansi.reset}:`);
|
|
373
392
|
for (const [model, stats] of Object.entries(summary.by_model)) {
|
|
374
393
|
const totalFmt = this.formatTokens(stats.total_tokens);
|
|
375
394
|
const promptFmt = this.formatTokens(stats.prompt_tokens);
|
|
@@ -378,7 +397,7 @@ export class TokenCost {
|
|
|
378
397
|
const costPart = this.includeCost && stats.cost > 0
|
|
379
398
|
? ` ($${stats.cost.toFixed(4)})`
|
|
380
399
|
: '';
|
|
381
|
-
costLogger.
|
|
400
|
+
costLogger.debug(` 🤖 ${ansi.cyan}${model}${ansi.reset}: ${ansi.blue}${totalFmt} tokens${ansi.reset}${costPart} | ` +
|
|
382
401
|
`⬅️ ${ansi.yellow}${promptFmt}${ansi.reset} | ➡️ ${ansi.green}${completionFmt}${ansi.reset} | ` +
|
|
383
402
|
`📞 ${stats.invocations} calls | 📈 ${avgFmt}/call`);
|
|
384
403
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const findUnsupportedJsonSchemaKeyword: (schema: unknown) => string | null;
|
|
3
|
+
export declare const schemaDictToZodSchema: (schema: unknown) => z.ZodTypeAny;
|
|
4
|
+
export declare const resolveDefaultForSchema: (schema: unknown) => unknown;
|
|
5
|
+
export declare const normalizeStructuredDataBySchema: (value: unknown, schema: unknown) => unknown;
|
|
6
|
+
export declare const schema_dict_to_zod_schema: (schema: unknown) => z.ZodTypeAny;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const UNSUPPORTED_KEYWORDS = new Set([
|
|
3
|
+
'$ref',
|
|
4
|
+
'allOf',
|
|
5
|
+
'anyOf',
|
|
6
|
+
'oneOf',
|
|
7
|
+
'not',
|
|
8
|
+
'$defs',
|
|
9
|
+
'definitions',
|
|
10
|
+
'if',
|
|
11
|
+
'then',
|
|
12
|
+
'else',
|
|
13
|
+
'dependentSchemas',
|
|
14
|
+
'dependentRequired',
|
|
15
|
+
]);
|
|
16
|
+
const PRIMITIVE_DEFAULTS = {
|
|
17
|
+
string: '',
|
|
18
|
+
number: 0.0,
|
|
19
|
+
integer: 0,
|
|
20
|
+
boolean: false,
|
|
21
|
+
};
|
|
22
|
+
const isRecord = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
23
|
+
const getTypeList = (schema) => {
|
|
24
|
+
const schemaType = schema.type;
|
|
25
|
+
if (Array.isArray(schemaType)) {
|
|
26
|
+
return schemaType.map((item) => String(item).toLowerCase());
|
|
27
|
+
}
|
|
28
|
+
if (typeof schemaType === 'string' && schemaType.trim().length > 0) {
|
|
29
|
+
return [schemaType.toLowerCase()];
|
|
30
|
+
}
|
|
31
|
+
return ['string'];
|
|
32
|
+
};
|
|
33
|
+
export const findUnsupportedJsonSchemaKeyword = (schema) => {
|
|
34
|
+
if (Array.isArray(schema)) {
|
|
35
|
+
for (const item of schema) {
|
|
36
|
+
const found = findUnsupportedJsonSchemaKeyword(item);
|
|
37
|
+
if (found) {
|
|
38
|
+
return found;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (!isRecord(schema)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
47
|
+
if (UNSUPPORTED_KEYWORDS.has(key)) {
|
|
48
|
+
return key;
|
|
49
|
+
}
|
|
50
|
+
const found = findUnsupportedJsonSchemaKeyword(value);
|
|
51
|
+
if (found) {
|
|
52
|
+
return found;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
const checkUnsupported = (schema) => {
|
|
58
|
+
const unsupported = findUnsupportedJsonSchemaKeyword(schema);
|
|
59
|
+
if (unsupported) {
|
|
60
|
+
throw new Error(`Unsupported JSON Schema keyword: ${unsupported}`);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const resolveType = (schema, name) => {
|
|
64
|
+
checkUnsupported(schema);
|
|
65
|
+
const typeList = getTypeList(schema);
|
|
66
|
+
if (Array.isArray(schema.enum)) {
|
|
67
|
+
return z.string();
|
|
68
|
+
}
|
|
69
|
+
if (typeList.includes('object')) {
|
|
70
|
+
const properties = isRecord(schema.properties)
|
|
71
|
+
? schema.properties
|
|
72
|
+
: null;
|
|
73
|
+
const base = properties
|
|
74
|
+
? buildObjectSchema(schema, name)
|
|
75
|
+
: z.record(z.string(), z.any());
|
|
76
|
+
return typeList.includes('null') || schema.nullable === true
|
|
77
|
+
? base.nullable()
|
|
78
|
+
: base;
|
|
79
|
+
}
|
|
80
|
+
if (typeList.includes('array')) {
|
|
81
|
+
const items = isRecord(schema.items)
|
|
82
|
+
? resolveType(schema.items, `${name}_item`)
|
|
83
|
+
: z.any();
|
|
84
|
+
const arraySchema = z.array(items);
|
|
85
|
+
return typeList.includes('null') || schema.nullable === true
|
|
86
|
+
? arraySchema.nullable()
|
|
87
|
+
: arraySchema;
|
|
88
|
+
}
|
|
89
|
+
let primitive = z.string();
|
|
90
|
+
if (typeList.includes('integer')) {
|
|
91
|
+
primitive = z.number().int();
|
|
92
|
+
}
|
|
93
|
+
else if (typeList.includes('number')) {
|
|
94
|
+
primitive = z.number();
|
|
95
|
+
}
|
|
96
|
+
else if (typeList.includes('boolean')) {
|
|
97
|
+
primitive = z.boolean();
|
|
98
|
+
}
|
|
99
|
+
else if (typeList.includes('null')) {
|
|
100
|
+
primitive = z.null();
|
|
101
|
+
}
|
|
102
|
+
else if (typeList.includes('string')) {
|
|
103
|
+
primitive = z.string();
|
|
104
|
+
}
|
|
105
|
+
if (schema.nullable === true && !typeList.includes('null')) {
|
|
106
|
+
return primitive.nullable();
|
|
107
|
+
}
|
|
108
|
+
return primitive;
|
|
109
|
+
};
|
|
110
|
+
const applyOptionalDefaults = (propertySchema, propertyType) => {
|
|
111
|
+
if (Object.prototype.hasOwnProperty.call(propertySchema, 'default')) {
|
|
112
|
+
return propertyType.default(propertySchema.default);
|
|
113
|
+
}
|
|
114
|
+
const typeList = getTypeList(propertySchema);
|
|
115
|
+
const allowsNull = propertySchema.nullable === true || typeList.includes('null');
|
|
116
|
+
if (allowsNull) {
|
|
117
|
+
return propertyType.nullable().default(null);
|
|
118
|
+
}
|
|
119
|
+
if (Array.isArray(propertySchema.enum)) {
|
|
120
|
+
return propertyType.nullable().default(null);
|
|
121
|
+
}
|
|
122
|
+
if (typeList.includes('array')) {
|
|
123
|
+
return propertyType.default([]);
|
|
124
|
+
}
|
|
125
|
+
const primitiveType = typeList.find((item) => item in PRIMITIVE_DEFAULTS);
|
|
126
|
+
if (primitiveType) {
|
|
127
|
+
return propertyType.default(PRIMITIVE_DEFAULTS[primitiveType]);
|
|
128
|
+
}
|
|
129
|
+
return propertyType.nullable().default(null);
|
|
130
|
+
};
|
|
131
|
+
const buildObjectSchema = (schema, name) => {
|
|
132
|
+
checkUnsupported(schema);
|
|
133
|
+
const properties = isRecord(schema.properties)
|
|
134
|
+
? schema.properties
|
|
135
|
+
: {};
|
|
136
|
+
const required = new Set(Array.isArray(schema.required)
|
|
137
|
+
? schema.required
|
|
138
|
+
.map((item) => String(item))
|
|
139
|
+
.filter((item) => item.length > 0)
|
|
140
|
+
: []);
|
|
141
|
+
const shape = {};
|
|
142
|
+
for (const [propertyName, propertySchema] of Object.entries(properties)) {
|
|
143
|
+
if (!isRecord(propertySchema)) {
|
|
144
|
+
shape[propertyName] = z.any();
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const propertyType = resolveType(propertySchema, `${name}_${propertyName}`);
|
|
148
|
+
if (required.has(propertyName)) {
|
|
149
|
+
shape[propertyName] = propertyType;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
shape[propertyName] = applyOptionalDefaults(propertySchema, propertyType);
|
|
153
|
+
}
|
|
154
|
+
return z.object(shape).strict();
|
|
155
|
+
};
|
|
156
|
+
export const schemaDictToZodSchema = (schema) => {
|
|
157
|
+
if (!isRecord(schema)) {
|
|
158
|
+
throw new Error('Top-level schema must be an object');
|
|
159
|
+
}
|
|
160
|
+
checkUnsupported(schema);
|
|
161
|
+
const typeList = getTypeList(schema);
|
|
162
|
+
if (!typeList.includes('object')) {
|
|
163
|
+
throw new Error('Top-level schema must have type "object"');
|
|
164
|
+
}
|
|
165
|
+
if (!isRecord(schema.properties) || !Object.keys(schema.properties).length) {
|
|
166
|
+
throw new Error('Top-level schema must have at least one property');
|
|
167
|
+
}
|
|
168
|
+
const modelName = typeof schema.title === 'string' && schema.title.trim().length > 0
|
|
169
|
+
? schema.title
|
|
170
|
+
: 'DynamicExtractionModel';
|
|
171
|
+
return buildObjectSchema(schema, modelName);
|
|
172
|
+
};
|
|
173
|
+
export const resolveDefaultForSchema = (schema) => {
|
|
174
|
+
if (!isRecord(schema)) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
if (Object.prototype.hasOwnProperty.call(schema, 'default')) {
|
|
178
|
+
return schema.default;
|
|
179
|
+
}
|
|
180
|
+
const typeList = getTypeList(schema);
|
|
181
|
+
const allowsNull = schema.nullable === true || typeList.includes('null');
|
|
182
|
+
if (allowsNull) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
if (Array.isArray(schema.enum)) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
if (typeList.includes('array')) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
const primitiveType = typeList.find((item) => item in PRIMITIVE_DEFAULTS);
|
|
192
|
+
if (primitiveType) {
|
|
193
|
+
return PRIMITIVE_DEFAULTS[primitiveType];
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
};
|
|
197
|
+
export const normalizeStructuredDataBySchema = (value, schema) => {
|
|
198
|
+
if (!isRecord(schema)) {
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
const typeList = getTypeList(schema);
|
|
202
|
+
if (typeList.includes('object')) {
|
|
203
|
+
const properties = isRecord(schema.properties)
|
|
204
|
+
? schema.properties
|
|
205
|
+
: {};
|
|
206
|
+
const required = new Set(Array.isArray(schema.required)
|
|
207
|
+
? schema.required
|
|
208
|
+
.map((item) => String(item))
|
|
209
|
+
.filter((item) => item.length > 0)
|
|
210
|
+
: []);
|
|
211
|
+
const source = isRecord(value) ? value : {};
|
|
212
|
+
const normalized = {};
|
|
213
|
+
for (const [propertyName, propertySchema] of Object.entries(properties)) {
|
|
214
|
+
if (Object.prototype.hasOwnProperty.call(source, propertyName)) {
|
|
215
|
+
normalized[propertyName] = normalizeStructuredDataBySchema(source[propertyName], propertySchema);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (required.has(propertyName)) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
normalized[propertyName] = resolveDefaultForSchema(propertySchema);
|
|
222
|
+
}
|
|
223
|
+
for (const [propertyName, propertyValue] of Object.entries(source)) {
|
|
224
|
+
if (!Object.prototype.hasOwnProperty.call(normalized, propertyName)) {
|
|
225
|
+
normalized[propertyName] = propertyValue;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return normalized;
|
|
229
|
+
}
|
|
230
|
+
if (typeList.includes('array') &&
|
|
231
|
+
Array.isArray(value) &&
|
|
232
|
+
isRecord(schema.items)) {
|
|
233
|
+
return value.map((item) => normalizeStructuredDataBySchema(item, schema.items));
|
|
234
|
+
}
|
|
235
|
+
return value;
|
|
236
|
+
};
|
|
237
|
+
export const schema_dict_to_zod_schema = schemaDictToZodSchema;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../controller/registry/service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../controller/registry/service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../controller/registry/views.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../controller/registry/views.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Controller as Tools } from '../controller/service.js';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DOMElementNode } from '../dom/views.js';
|
|
2
|
+
const normalizeBoolLike = (value) => {
|
|
3
|
+
const normalized = String(value ?? '')
|
|
4
|
+
.trim()
|
|
5
|
+
.toLowerCase();
|
|
6
|
+
return normalized === 'true' || normalized === 'checked' || normalized === '';
|
|
7
|
+
};
|
|
8
|
+
const summarizeText = (text, maxLength = 30) => {
|
|
9
|
+
const compact = text.replace(/\s+/g, ' ').trim();
|
|
10
|
+
if (!compact) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
return compact.length > maxLength
|
|
14
|
+
? `${compact.slice(0, maxLength)}...`
|
|
15
|
+
: compact;
|
|
16
|
+
};
|
|
17
|
+
export const getClickDescription = (node) => {
|
|
18
|
+
const parts = [node.tag_name];
|
|
19
|
+
const inputType = node.attributes.type;
|
|
20
|
+
if (node.tag_name === 'input' && inputType) {
|
|
21
|
+
parts.push(`type=${inputType}`);
|
|
22
|
+
if (inputType === 'checkbox') {
|
|
23
|
+
const isChecked = normalizeBoolLike(node.attributes.checked);
|
|
24
|
+
parts.push(`checkbox-state=${isChecked ? 'checked' : 'unchecked'}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const role = node.attributes.role;
|
|
28
|
+
if (role) {
|
|
29
|
+
parts.push(`role=${role}`);
|
|
30
|
+
if (role === 'checkbox') {
|
|
31
|
+
const isChecked = normalizeBoolLike(node.attributes['aria-checked']);
|
|
32
|
+
parts.push(`checkbox-state=${isChecked ? 'checked' : 'unchecked'}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (['label', 'span', 'div'].includes(node.tag_name) &&
|
|
36
|
+
!parts.some((part) => part.startsWith('type='))) {
|
|
37
|
+
const hiddenCheckboxChild = node.children.find((child) => child instanceof DOMElementNode &&
|
|
38
|
+
child.tag_name === 'input' &&
|
|
39
|
+
child.attributes.type === 'checkbox' &&
|
|
40
|
+
!child.is_visible);
|
|
41
|
+
if (hiddenCheckboxChild) {
|
|
42
|
+
const isChecked = normalizeBoolLike(hiddenCheckboxChild.attributes.checked);
|
|
43
|
+
parts.push(`checkbox-state=${isChecked ? 'checked' : 'unchecked'}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const text = summarizeText(node.get_all_text_till_next_clickable_element());
|
|
47
|
+
if (text) {
|
|
48
|
+
parts.push(`"${text}"`);
|
|
49
|
+
}
|
|
50
|
+
for (const attribute of ['id', 'name', 'aria-label']) {
|
|
51
|
+
const value = node.attributes[attribute];
|
|
52
|
+
if (value && value.trim().length > 0) {
|
|
53
|
+
parts.push(`${attribute}=${value.slice(0, 20)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return parts.join(' ');
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../controller/views.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../controller/views.js';
|