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.
Files changed (259) hide show
  1. package/README.md +295 -686
  2. package/dist/actor/element.d.ts +19 -0
  3. package/dist/actor/element.js +46 -0
  4. package/dist/actor/index.d.ts +4 -0
  5. package/dist/actor/index.js +4 -0
  6. package/dist/actor/mouse.d.ts +19 -0
  7. package/dist/actor/mouse.js +39 -0
  8. package/dist/actor/page.d.ts +29 -0
  9. package/dist/actor/page.js +88 -0
  10. package/dist/actor/utils.d.ts +4 -0
  11. package/dist/actor/utils.js +35 -0
  12. package/dist/agent/cloud-events.d.ts +18 -0
  13. package/dist/agent/cloud-events.js +65 -2
  14. package/dist/agent/gif.d.ts +1 -0
  15. package/dist/agent/gif.js +24 -2
  16. package/dist/agent/judge.d.ts +17 -0
  17. package/dist/agent/judge.js +197 -0
  18. package/dist/agent/message-manager/service.d.ts +12 -4
  19. package/dist/agent/message-manager/service.js +205 -39
  20. package/dist/agent/message-manager/utils.js +0 -1
  21. package/dist/agent/message-manager/views.d.ts +4 -0
  22. package/dist/agent/message-manager/views.js +11 -7
  23. package/dist/agent/prompts.d.ts +24 -3
  24. package/dist/agent/prompts.js +274 -59
  25. package/dist/agent/service.d.ts +99 -41
  26. package/dist/agent/service.js +2266 -472
  27. package/dist/agent/variable-detector.d.ts +12 -0
  28. package/dist/agent/variable-detector.js +211 -0
  29. package/dist/agent/views.d.ts +237 -18
  30. package/dist/agent/views.js +446 -33
  31. package/dist/browser/cloud/cloud.d.ts +20 -0
  32. package/dist/browser/cloud/cloud.js +129 -0
  33. package/dist/browser/cloud/index.d.ts +2 -0
  34. package/dist/browser/cloud/index.js +2 -0
  35. package/dist/browser/cloud/views.d.ts +41 -0
  36. package/dist/browser/cloud/views.js +35 -0
  37. package/dist/browser/events.d.ts +345 -0
  38. package/dist/browser/events.js +566 -0
  39. package/dist/browser/extensions.js +17 -17
  40. package/dist/browser/index.d.ts +4 -0
  41. package/dist/browser/index.js +4 -0
  42. package/dist/browser/profile.d.ts +8 -2
  43. package/dist/browser/profile.js +79 -12
  44. package/dist/browser/session-manager.d.ts +85 -0
  45. package/dist/browser/session-manager.js +208 -0
  46. package/dist/browser/session.d.ts +100 -8
  47. package/dist/browser/session.js +1097 -58
  48. package/dist/browser/types.d.ts +0 -2
  49. package/dist/browser/views.d.ts +39 -0
  50. package/dist/browser/views.js +32 -0
  51. package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
  52. package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
  53. package/dist/browser/watchdogs/base.d.ts +21 -0
  54. package/dist/browser/watchdogs/base.js +81 -0
  55. package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
  56. package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
  57. package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
  58. package/dist/browser/watchdogs/crash-watchdog.js +296 -0
  59. package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
  60. package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
  61. package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
  62. package/dist/browser/watchdogs/dom-watchdog.js +31 -0
  63. package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
  64. package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
  65. package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
  66. package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
  67. package/dist/browser/watchdogs/index.d.ts +15 -0
  68. package/dist/browser/watchdogs/index.js +15 -0
  69. package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
  70. package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
  71. package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
  72. package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
  73. package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
  74. package/dist/browser/watchdogs/popups-watchdog.js +77 -0
  75. package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
  76. package/dist/browser/watchdogs/recording-watchdog.js +249 -0
  77. package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
  78. package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
  79. package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
  80. package/dist/browser/watchdogs/security-watchdog.js +84 -0
  81. package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
  82. package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
  83. package/dist/cli.d.ts +7 -2
  84. package/dist/cli.js +182 -25
  85. package/dist/code-use/formatting.d.ts +3 -0
  86. package/dist/code-use/formatting.js +18 -0
  87. package/dist/code-use/index.d.ts +6 -0
  88. package/dist/code-use/index.js +6 -0
  89. package/dist/code-use/namespace.d.ts +5 -0
  90. package/dist/code-use/namespace.js +81 -0
  91. package/dist/code-use/notebook-export.d.ts +3 -0
  92. package/dist/code-use/notebook-export.js +56 -0
  93. package/dist/code-use/service.d.ts +24 -0
  94. package/dist/code-use/service.js +104 -0
  95. package/dist/code-use/utils.d.ts +4 -0
  96. package/dist/code-use/utils.js +98 -0
  97. package/dist/code-use/views.d.ts +108 -0
  98. package/dist/code-use/views.js +165 -0
  99. package/dist/config.d.ts +13 -0
  100. package/dist/config.js +69 -3
  101. package/dist/controller/registry/service.d.ts +10 -1
  102. package/dist/controller/registry/service.js +266 -10
  103. package/dist/controller/registry/views.d.ts +4 -1
  104. package/dist/controller/registry/views.js +25 -2
  105. package/dist/controller/service.d.ts +10 -1
  106. package/dist/controller/service.js +1807 -268
  107. package/dist/controller/views.d.ts +78 -155
  108. package/dist/controller/views.js +61 -12
  109. package/dist/dom/history-tree-processor/service.d.ts +5 -0
  110. package/dist/dom/history-tree-processor/service.js +169 -14
  111. package/dist/dom/history-tree-processor/view.d.ts +7 -1
  112. package/dist/dom/history-tree-processor/view.js +10 -1
  113. package/dist/dom/markdown-extractor.d.ts +37 -0
  114. package/dist/dom/markdown-extractor.js +345 -0
  115. package/dist/dom/service.d.ts +3 -1
  116. package/dist/dom/service.js +76 -0
  117. package/dist/dom/views.d.ts +1 -0
  118. package/dist/dom/views.js +45 -0
  119. package/dist/event-bus.d.ts +107 -7
  120. package/dist/event-bus.js +313 -10
  121. package/dist/exceptions.d.ts +0 -3
  122. package/dist/exceptions.js +0 -7
  123. package/dist/filesystem/file-system.d.ts +18 -0
  124. package/dist/filesystem/file-system.js +503 -42
  125. package/dist/index.d.ts +7 -0
  126. package/dist/index.js +6 -0
  127. package/dist/integrations/gmail/actions.d.ts +3 -3
  128. package/dist/integrations/gmail/actions.js +4 -4
  129. package/dist/llm/anthropic/chat.d.ts +18 -1
  130. package/dist/llm/anthropic/chat.js +123 -55
  131. package/dist/llm/anthropic/serializer.d.ts +2 -0
  132. package/dist/llm/anthropic/serializer.js +81 -9
  133. package/dist/llm/aws/chat-anthropic.d.ts +17 -0
  134. package/dist/llm/aws/chat-anthropic.js +126 -26
  135. package/dist/llm/aws/chat-bedrock.d.ts +28 -1
  136. package/dist/llm/aws/chat-bedrock.js +161 -34
  137. package/dist/llm/aws/serializer.d.ts +13 -1
  138. package/dist/llm/aws/serializer.js +56 -17
  139. package/dist/llm/azure/chat.d.ts +53 -2
  140. package/dist/llm/azure/chat.js +366 -54
  141. package/dist/llm/base.d.ts +2 -0
  142. package/dist/llm/browser-use/chat.d.ts +40 -0
  143. package/dist/llm/browser-use/chat.js +305 -0
  144. package/dist/llm/browser-use/index.d.ts +1 -0
  145. package/dist/llm/browser-use/index.js +1 -0
  146. package/dist/llm/cerebras/chat.d.ts +39 -0
  147. package/dist/llm/cerebras/chat.js +178 -0
  148. package/dist/llm/cerebras/index.d.ts +2 -0
  149. package/dist/llm/cerebras/index.js +2 -0
  150. package/dist/llm/cerebras/serializer.d.ts +7 -0
  151. package/dist/llm/cerebras/serializer.js +82 -0
  152. package/dist/llm/deepseek/chat.d.ts +19 -2
  153. package/dist/llm/deepseek/chat.js +138 -25
  154. package/dist/llm/google/chat.d.ts +46 -2
  155. package/dist/llm/google/chat.js +267 -64
  156. package/dist/llm/google/serializer.d.ts +9 -1
  157. package/dist/llm/google/serializer.js +141 -34
  158. package/dist/llm/groq/chat.d.ts +21 -2
  159. package/dist/llm/groq/chat.js +125 -26
  160. package/dist/llm/groq/parser.js +3 -1
  161. package/dist/llm/mistral/chat.d.ts +43 -0
  162. package/dist/llm/mistral/chat.js +154 -0
  163. package/dist/llm/mistral/index.d.ts +2 -0
  164. package/dist/llm/mistral/index.js +2 -0
  165. package/dist/llm/mistral/schema.d.ts +8 -0
  166. package/dist/llm/mistral/schema.js +27 -0
  167. package/dist/llm/models.d.ts +2 -0
  168. package/dist/llm/models.js +317 -0
  169. package/dist/llm/ollama/chat.d.ts +13 -1
  170. package/dist/llm/ollama/chat.js +110 -19
  171. package/dist/llm/ollama/serializer.d.ts +1 -0
  172. package/dist/llm/ollama/serializer.js +34 -12
  173. package/dist/llm/openai/chat.d.ts +16 -0
  174. package/dist/llm/openai/chat.js +94 -44
  175. package/dist/llm/openai/like.d.ts +5 -3
  176. package/dist/llm/openai/like.js +7 -3
  177. package/dist/llm/openai/responses-serializer.d.ts +18 -0
  178. package/dist/llm/openai/responses-serializer.js +72 -0
  179. package/dist/llm/openrouter/chat.d.ts +28 -2
  180. package/dist/llm/openrouter/chat.js +115 -29
  181. package/dist/llm/schema.d.ts +11 -1
  182. package/dist/llm/schema.js +81 -1
  183. package/dist/llm/vercel/chat.d.ts +50 -0
  184. package/dist/llm/vercel/chat.js +276 -0
  185. package/dist/llm/vercel/index.d.ts +1 -0
  186. package/dist/llm/vercel/index.js +1 -0
  187. package/dist/llm/vercel/serializer.d.ts +5 -0
  188. package/dist/llm/vercel/serializer.js +7 -0
  189. package/dist/llm/views.d.ts +2 -1
  190. package/dist/llm/views.js +3 -1
  191. package/dist/logging-config.d.ts +2 -0
  192. package/dist/logging-config.js +82 -29
  193. package/dist/mcp/client.d.ts +10 -5
  194. package/dist/mcp/client.js +14 -9
  195. package/dist/mcp/controller.d.ts +42 -3
  196. package/dist/mcp/controller.js +56 -31
  197. package/dist/mcp/server.d.ts +14 -0
  198. package/dist/mcp/server.js +255 -52
  199. package/dist/observability.js +10 -4
  200. package/dist/sandbox/index.d.ts +2 -0
  201. package/dist/sandbox/index.js +2 -0
  202. package/dist/sandbox/sandbox.d.ts +19 -0
  203. package/dist/sandbox/sandbox.js +140 -0
  204. package/dist/sandbox/views.d.ts +67 -0
  205. package/dist/sandbox/views.js +121 -0
  206. package/dist/skill-cli/index.d.ts +3 -0
  207. package/dist/skill-cli/index.js +3 -0
  208. package/dist/skill-cli/protocol.d.ts +30 -0
  209. package/dist/skill-cli/protocol.js +48 -0
  210. package/dist/skill-cli/server.d.ts +11 -0
  211. package/dist/skill-cli/server.js +85 -0
  212. package/dist/skill-cli/sessions.d.ts +24 -0
  213. package/dist/skill-cli/sessions.js +47 -0
  214. package/dist/skills/index.d.ts +3 -0
  215. package/dist/skills/index.js +3 -0
  216. package/dist/skills/service.d.ts +27 -0
  217. package/dist/skills/service.js +266 -0
  218. package/dist/skills/utils.d.ts +6 -0
  219. package/dist/skills/utils.js +53 -0
  220. package/dist/skills/views.d.ts +40 -0
  221. package/dist/skills/views.js +10 -0
  222. package/dist/sync/auth.js +8 -3
  223. package/dist/sync/service.d.ts +6 -6
  224. package/dist/sync/service.js +54 -89
  225. package/dist/telemetry/views.d.ts +20 -6
  226. package/dist/telemetry/views.js +23 -5
  227. package/dist/tokens/custom-pricing.d.ts +2 -0
  228. package/dist/tokens/custom-pricing.js +22 -0
  229. package/dist/tokens/index.d.ts +2 -0
  230. package/dist/tokens/index.js +2 -0
  231. package/dist/tokens/mappings.d.ts +1 -0
  232. package/dist/tokens/mappings.js +3 -0
  233. package/dist/tokens/service.js +27 -8
  234. package/dist/tools/extraction/index.d.ts +2 -0
  235. package/dist/tools/extraction/index.js +2 -0
  236. package/dist/tools/extraction/schema-utils.d.ts +6 -0
  237. package/dist/tools/extraction/schema-utils.js +237 -0
  238. package/dist/tools/extraction/views.d.ts +7 -0
  239. package/dist/tools/index.d.ts +5 -0
  240. package/dist/tools/index.js +5 -0
  241. package/dist/tools/registry/index.d.ts +2 -0
  242. package/dist/tools/registry/index.js +2 -0
  243. package/dist/tools/registry/service.d.ts +1 -0
  244. package/dist/tools/registry/service.js +1 -0
  245. package/dist/tools/registry/views.d.ts +1 -0
  246. package/dist/tools/registry/views.js +1 -0
  247. package/dist/tools/service.d.ts +2 -0
  248. package/dist/tools/service.js +1 -0
  249. package/dist/tools/utils.d.ts +2 -0
  250. package/dist/tools/utils.js +57 -0
  251. package/dist/tools/views.d.ts +1 -0
  252. package/dist/tools/views.js +1 -0
  253. package/dist/utils.d.ts +10 -1
  254. package/dist/utils.js +70 -3
  255. package/package.json +87 -26
  256. package/dist/dom/playground/process-dom.js +0 -5
  257. package/dist/dom/playground/test-accessibility.d.ts +0 -44
  258. package/dist/dom/playground/test-accessibility.js +0 -111
  259. /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 {
@@ -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 Object.fromEntries(entries);
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,2 @@
1
+ import type { ModelPricing } from './views.js';
2
+ export declare const CUSTOM_MODEL_PRICING: Record<string, Partial<ModelPricing> & Record<string, number | null | string>>;
@@ -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'];
@@ -1,2 +1,4 @@
1
1
  export * from './service.js';
2
2
  export * from './views.js';
3
+ export * from './custom-pricing.js';
4
+ export * from './mappings.js';
@@ -1,2 +1,4 @@
1
1
  export * from './service.js';
2
2
  export * from './views.js';
3
+ export * from './custom-pricing.js';
4
+ export * from './mappings.js';
@@ -0,0 +1 @@
1
+ export declare const MODEL_TO_LITELLM: Record<string, string>;
@@ -0,0 +1,3 @@
1
+ export const MODEL_TO_LITELLM = {
2
+ 'gemini-flash-latest': 'gemini/gemini-flash-latest',
3
+ };
@@ -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.warning(`Failed to load token pricing cache: ${error.message}`);
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.error(`Failed to fetch LiteLLM pricing: ${error.message}`);
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).catch(() => undefined);
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.info(`🧠 ${ansi.cyan}${model}${ansi.reset} | ${inputPart} | ${completionSection}`);
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 pricing = this.pricingData[modelName];
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.info(`💲 ${ansi.bold}Total Usage Summary${ansi.reset}: ${ansi.blue}${totalTokens} tokens${ansi.reset}${totalCostPart} | ` +
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.info(` 🤖 ${ansi.cyan}${model}${ansi.reset}: ${ansi.blue}${totalFmt} tokens${ansi.reset}${costPart} | ` +
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,2 @@
1
+ export * from './schema-utils.js';
2
+ export * from './views.js';
@@ -0,0 +1,2 @@
1
+ export * from './schema-utils.js';
2
+ export * from './views.js';
@@ -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,7 @@
1
+ export interface ExtractionResult {
2
+ data: Record<string, unknown>;
3
+ schema_used: Record<string, unknown>;
4
+ is_partial?: boolean;
5
+ source_url?: string | null;
6
+ content_stats?: Record<string, unknown>;
7
+ }
@@ -0,0 +1,5 @@
1
+ export * from './service.js';
2
+ export * from './views.js';
3
+ export * from './registry/index.js';
4
+ export * from './extraction/index.js';
5
+ export * from './utils.js';
@@ -0,0 +1,5 @@
1
+ export * from './service.js';
2
+ export * from './views.js';
3
+ export * from './registry/index.js';
4
+ export * from './extraction/index.js';
5
+ export * from './utils.js';
@@ -0,0 +1,2 @@
1
+ export * from './service.js';
2
+ export * from './views.js';
@@ -0,0 +1,2 @@
1
+ export * from './service.js';
2
+ export * from './views.js';
@@ -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,2 @@
1
+ export { Controller as Tools } from '../controller/service.js';
2
+ export type { ControllerOptions as ToolsOptions, ActParams as ToolsActParams, } from '../controller/service.js';
@@ -0,0 +1 @@
1
+ export { Controller as Tools } from '../controller/service.js';
@@ -0,0 +1,2 @@
1
+ import { DOMElementNode } from '../dom/views.js';
2
+ export declare const getClickDescription: (node: DOMElementNode) => string;
@@ -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';