browser-use 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +103 -41
  26. package/dist/agent/service.js +2336 -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 +10 -4
  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 +105 -9
  47. package/dist/browser/session.js +1166 -95
  48. package/dist/browser/types.d.ts +153 -156
  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 +15 -0
  100. package/dist/config.js +109 -7
  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 +1814 -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 +109 -4
  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 +15 -0
  198. package/dist/mcp/server.js +261 -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 +116 -49
  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
@@ -1,15 +1,66 @@
1
1
  import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
2
- import { ChatInvokeCompletion } from '../views.js';
3
2
  import type { Message } from '../messages.js';
3
+ import { ChatInvokeCompletion } from '../views.js';
4
+ export interface ChatAzureOptions {
5
+ model?: string;
6
+ apiKey?: string;
7
+ endpoint?: string;
8
+ baseURL?: string;
9
+ apiVersion?: string;
10
+ deployment?: string;
11
+ azureAdToken?: string | null;
12
+ azureAdTokenProvider?: (() => Promise<string>) | null;
13
+ timeout?: number | null;
14
+ temperature?: number | null;
15
+ frequencyPenalty?: number | null;
16
+ reasoningEffort?: 'low' | 'medium' | 'high';
17
+ serviceTier?: 'auto' | 'default' | 'flex' | 'priority' | 'scale' | null;
18
+ maxCompletionTokens?: number | null;
19
+ topP?: number | null;
20
+ seed?: number | null;
21
+ maxRetries?: number;
22
+ defaultHeaders?: Record<string, string> | null;
23
+ defaultQuery?: Record<string, string | undefined> | null;
24
+ fetchImplementation?: typeof fetch;
25
+ fetchOptions?: RequestInit | null;
26
+ useResponsesApi?: boolean | 'auto';
27
+ addSchemaToSystemPrompt?: boolean;
28
+ dontForceStructuredOutput?: boolean;
29
+ removeMinItemsFromSchema?: boolean;
30
+ removeDefaultsFromSchema?: boolean;
31
+ }
4
32
  export declare class ChatAzure implements BaseChatModel {
5
33
  model: string;
6
34
  provider: string;
7
35
  private client;
8
- constructor(model?: string);
36
+ private temperature;
37
+ private frequencyPenalty;
38
+ private reasoningEffort;
39
+ private serviceTier;
40
+ private maxCompletionTokens;
41
+ private topP;
42
+ private seed;
43
+ private useResponsesApi;
44
+ private addSchemaToSystemPrompt;
45
+ private dontForceStructuredOutput;
46
+ private removeMinItemsFromSchema;
47
+ private removeDefaultsFromSchema;
48
+ constructor(options?: string | ChatAzureOptions);
9
49
  get name(): string;
10
50
  get model_name(): string;
51
+ private isReasoningModel;
52
+ private shouldUseResponsesApi;
53
+ private getChatUsage;
54
+ private getResponsesUsage;
55
+ private getResponseOutputText;
56
+ private getModelParamsForCompletions;
57
+ private getModelParamsForResponses;
58
+ private getZodSchemaCandidate;
59
+ private applySchemaToSystemMessage;
11
60
  ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
12
61
  ainvoke<T>(messages: Message[], output_format: {
13
62
  parse: (input: string) => T;
14
63
  } | undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<T>>;
64
+ private invokeChatCompletions;
65
+ private invokeResponses;
15
66
  }
@@ -1,17 +1,74 @@
1
1
  import { AzureOpenAI } from 'openai';
2
- import { ChatInvokeCompletion } from '../views.js';
2
+ import { ModelProviderError, ModelRateLimitError } from '../exceptions.js';
3
3
  import { OpenAIMessageSerializer } from '../openai/serializer.js';
4
+ import { ResponsesAPIMessageSerializer } from '../openai/responses-serializer.js';
5
+ import { SchemaOptimizer, zodSchemaToJsonSchema } from '../schema.js';
6
+ import { ChatInvokeCompletion } from '../views.js';
7
+ const RESPONSES_API_ONLY_MODELS = [
8
+ 'gpt-5.1-codex',
9
+ 'gpt-5.1-codex-mini',
10
+ 'gpt-5.1-codex-max',
11
+ 'gpt-5-codex',
12
+ 'codex-mini-latest',
13
+ 'computer-use-preview',
14
+ ];
15
+ const REASONING_MODELS = [
16
+ 'o4-mini',
17
+ 'o3',
18
+ 'o3-mini',
19
+ 'o1',
20
+ 'o1-pro',
21
+ 'o3-pro',
22
+ 'gpt-5',
23
+ 'gpt-5-mini',
24
+ 'gpt-5-nano',
25
+ ];
4
26
  export class ChatAzure {
5
27
  model;
6
28
  provider = 'azure';
7
29
  client;
8
- constructor(model = 'gpt-4o') {
30
+ temperature;
31
+ frequencyPenalty;
32
+ reasoningEffort;
33
+ serviceTier;
34
+ maxCompletionTokens;
35
+ topP;
36
+ seed;
37
+ useResponsesApi;
38
+ addSchemaToSystemPrompt;
39
+ dontForceStructuredOutput;
40
+ removeMinItemsFromSchema;
41
+ removeDefaultsFromSchema;
42
+ constructor(options = {}) {
43
+ const normalizedOptions = typeof options === 'string' ? { model: options } : options;
44
+ const { model = 'gpt-4o', apiKey = process.env.AZURE_OPENAI_API_KEY ?? process.env.AZURE_OPENAI_KEY, endpoint = process.env.AZURE_OPENAI_ENDPOINT, baseURL = undefined, apiVersion = process.env.AZURE_OPENAI_API_VERSION ?? '2024-12-01-preview', deployment = process.env.AZURE_OPENAI_DEPLOYMENT ?? model, azureAdToken = null, azureAdTokenProvider = null, timeout = null, temperature = 0.2, frequencyPenalty = 0.3, reasoningEffort = 'low', serviceTier = null, maxCompletionTokens = 4096, topP = null, seed = null, maxRetries = 5, defaultHeaders = null, defaultQuery = null, fetchImplementation, fetchOptions = null, useResponsesApi = 'auto', addSchemaToSystemPrompt = false, dontForceStructuredOutput = false, removeMinItemsFromSchema = false, removeDefaultsFromSchema = false, } = normalizedOptions;
9
45
  this.model = model;
46
+ this.temperature = temperature;
47
+ this.frequencyPenalty = frequencyPenalty;
48
+ this.reasoningEffort = reasoningEffort;
49
+ this.serviceTier = serviceTier;
50
+ this.maxCompletionTokens = maxCompletionTokens;
51
+ this.topP = topP;
52
+ this.seed = seed;
53
+ this.useResponsesApi = useResponsesApi;
54
+ this.addSchemaToSystemPrompt = addSchemaToSystemPrompt;
55
+ this.dontForceStructuredOutput = dontForceStructuredOutput;
56
+ this.removeMinItemsFromSchema = removeMinItemsFromSchema;
57
+ this.removeDefaultsFromSchema = removeDefaultsFromSchema;
10
58
  this.client = new AzureOpenAI({
11
- apiKey: process.env.AZURE_OPENAI_API_KEY,
12
- endpoint: process.env.AZURE_OPENAI_ENDPOINT,
13
- apiVersion: process.env.AZURE_OPENAI_API_VERSION || '2024-05-01-preview',
14
- deployment: model,
59
+ apiKey,
60
+ endpoint,
61
+ baseURL,
62
+ apiVersion,
63
+ deployment,
64
+ azureADTokenProvider: azureAdTokenProvider ??
65
+ (azureAdToken ? async () => String(azureAdToken) : undefined),
66
+ timeout: timeout ?? undefined,
67
+ maxRetries,
68
+ defaultHeaders: defaultHeaders ?? undefined,
69
+ defaultQuery: defaultQuery ?? undefined,
70
+ fetch: fetchImplementation,
71
+ fetchOptions: (fetchOptions ?? undefined),
15
72
  });
16
73
  }
17
74
  get name() {
@@ -20,65 +77,320 @@ export class ChatAzure {
20
77
  get model_name() {
21
78
  return this.model;
22
79
  }
80
+ isReasoningModel() {
81
+ return REASONING_MODELS.some((m) => this.model.toLowerCase().includes(m.toLowerCase()));
82
+ }
83
+ shouldUseResponsesApi() {
84
+ if (typeof this.useResponsesApi === 'boolean') {
85
+ return this.useResponsesApi;
86
+ }
87
+ return RESPONSES_API_ONLY_MODELS.some((name) => this.model.toLowerCase().includes(name.toLowerCase()));
88
+ }
89
+ getChatUsage(response) {
90
+ if (!response?.usage) {
91
+ return null;
92
+ }
93
+ let completionTokens = response.usage.completion_tokens;
94
+ const completionDetails = response.usage.completion_tokens_details;
95
+ if (completionDetails?.reasoning_tokens) {
96
+ completionTokens += completionDetails.reasoning_tokens;
97
+ }
98
+ return {
99
+ prompt_tokens: response.usage.prompt_tokens,
100
+ prompt_cached_tokens: response.usage.prompt_tokens_details?.cached_tokens ?? null,
101
+ prompt_cache_creation_tokens: null,
102
+ prompt_image_tokens: null,
103
+ completion_tokens: completionTokens,
104
+ total_tokens: response.usage.total_tokens,
105
+ };
106
+ }
107
+ getResponsesUsage(response) {
108
+ if (!response?.usage) {
109
+ return null;
110
+ }
111
+ return {
112
+ prompt_tokens: response.usage.input_tokens ?? 0,
113
+ prompt_cached_tokens: response.usage.input_tokens_details?.cached_tokens ?? null,
114
+ prompt_cache_creation_tokens: null,
115
+ prompt_image_tokens: null,
116
+ completion_tokens: response.usage.output_tokens ?? 0,
117
+ total_tokens: response.usage.total_tokens ?? 0,
118
+ };
119
+ }
120
+ getResponseOutputText(response) {
121
+ if (typeof response?.output_text === 'string') {
122
+ return response.output_text;
123
+ }
124
+ const outputs = Array.isArray(response?.output) ? response.output : [];
125
+ for (const item of outputs) {
126
+ if (Array.isArray(item?.content)) {
127
+ for (const part of item.content) {
128
+ if (typeof part?.text === 'string') {
129
+ return part.text;
130
+ }
131
+ if (typeof part?.output_text === 'string') {
132
+ return part.output_text;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ return '';
138
+ }
139
+ getModelParamsForCompletions() {
140
+ const modelParams = {};
141
+ if (!this.isReasoningModel()) {
142
+ if (this.temperature !== null) {
143
+ modelParams.temperature = this.temperature;
144
+ }
145
+ if (this.frequencyPenalty !== null) {
146
+ modelParams.frequency_penalty = this.frequencyPenalty;
147
+ }
148
+ }
149
+ else {
150
+ modelParams.reasoning_effort = this.reasoningEffort;
151
+ }
152
+ if (this.maxCompletionTokens !== null) {
153
+ modelParams.max_completion_tokens = this.maxCompletionTokens;
154
+ }
155
+ if (this.topP !== null) {
156
+ modelParams.top_p = this.topP;
157
+ }
158
+ if (this.seed !== null) {
159
+ modelParams.seed = this.seed;
160
+ }
161
+ if (this.serviceTier !== null) {
162
+ modelParams.service_tier = this.serviceTier;
163
+ }
164
+ return modelParams;
165
+ }
166
+ getModelParamsForResponses() {
167
+ const modelParams = {};
168
+ if (!this.isReasoningModel()) {
169
+ if (this.temperature !== null) {
170
+ modelParams.temperature = this.temperature;
171
+ }
172
+ if (this.frequencyPenalty !== null) {
173
+ modelParams.frequency_penalty = this.frequencyPenalty;
174
+ }
175
+ }
176
+ else {
177
+ modelParams.reasoning = { effort: this.reasoningEffort };
178
+ }
179
+ if (this.maxCompletionTokens !== null) {
180
+ modelParams.max_output_tokens = this.maxCompletionTokens;
181
+ }
182
+ if (this.topP !== null) {
183
+ modelParams.top_p = this.topP;
184
+ }
185
+ if (this.seed !== null) {
186
+ modelParams.seed = this.seed;
187
+ }
188
+ if (this.serviceTier !== null) {
189
+ modelParams.service_tier = this.serviceTier;
190
+ }
191
+ return modelParams;
192
+ }
193
+ getZodSchemaCandidate(output_format) {
194
+ const output = output_format;
195
+ if (output &&
196
+ typeof output === 'object' &&
197
+ typeof output.safeParse === 'function' &&
198
+ typeof output.parse === 'function') {
199
+ return output;
200
+ }
201
+ if (output &&
202
+ typeof output === 'object' &&
203
+ output.schema &&
204
+ typeof output.schema.safeParse === 'function' &&
205
+ typeof output.schema.parse === 'function') {
206
+ return output.schema;
207
+ }
208
+ return null;
209
+ }
210
+ applySchemaToSystemMessage(openaiMessages, responseJsonSchema) {
211
+ if (!this.addSchemaToSystemPrompt || openaiMessages.length === 0) {
212
+ return;
213
+ }
214
+ const firstMessage = openaiMessages[0];
215
+ if (firstMessage?.role !== 'system') {
216
+ return;
217
+ }
218
+ const schemaText = `\n<json_schema>\n` +
219
+ `${JSON.stringify(responseJsonSchema, null, 2)}\n` +
220
+ `</json_schema>`;
221
+ if (typeof firstMessage.content === 'string') {
222
+ firstMessage.content = (firstMessage.content ?? '') + schemaText;
223
+ return;
224
+ }
225
+ if (Array.isArray(firstMessage.content)) {
226
+ firstMessage.content = [
227
+ ...firstMessage.content,
228
+ { type: 'text', text: schemaText },
229
+ ];
230
+ }
231
+ }
23
232
  async ainvoke(messages, output_format, options = {}) {
233
+ const zodSchemaCandidate = this.getZodSchemaCandidate(output_format);
234
+ if (this.shouldUseResponsesApi()) {
235
+ return this.invokeResponses(messages, output_format, zodSchemaCandidate, options);
236
+ }
237
+ return this.invokeChatCompletions(messages, output_format, zodSchemaCandidate, options);
238
+ }
239
+ async invokeChatCompletions(messages, output_format, zodSchemaCandidate, options) {
24
240
  const serializer = new OpenAIMessageSerializer();
25
241
  const openaiMessages = serializer.serialize(messages);
26
- // Use simple json_object format for better compatibility with Azure
27
- // json_schema format may not be supported on all Azure API versions/deployments
28
- const responseFormat = output_format
29
- ? { type: 'json_object' }
30
- : undefined;
31
- const response = await this.client.chat.completions.create({
242
+ let responseFormat = undefined;
243
+ if (zodSchemaCandidate) {
244
+ try {
245
+ const rawJsonSchema = zodSchemaToJsonSchema(zodSchemaCandidate, {
246
+ name: 'agent_output',
247
+ target: 'jsonSchema7',
248
+ });
249
+ const optimizedJsonSchema = SchemaOptimizer.createOptimizedJsonSchema(rawJsonSchema, {
250
+ removeMinItems: this.removeMinItemsFromSchema,
251
+ removeDefaults: this.removeDefaultsFromSchema,
252
+ });
253
+ const responseJsonSchema = {
254
+ name: 'agent_output',
255
+ schema: optimizedJsonSchema,
256
+ strict: true,
257
+ };
258
+ this.applySchemaToSystemMessage(openaiMessages, responseJsonSchema);
259
+ if (!this.dontForceStructuredOutput) {
260
+ responseFormat = {
261
+ type: 'json_schema',
262
+ json_schema: responseJsonSchema,
263
+ };
264
+ }
265
+ }
266
+ catch {
267
+ responseFormat = undefined;
268
+ }
269
+ }
270
+ try {
271
+ const response = await this.client.chat.completions.create({
272
+ model: this.model,
273
+ messages: openaiMessages,
274
+ response_format: responseFormat,
275
+ ...this.getModelParamsForCompletions(),
276
+ }, options.signal ? { signal: options.signal } : undefined);
277
+ const content = response.choices[0].message.content || '';
278
+ const usage = this.getChatUsage(response);
279
+ const stopReason = response.choices[0].finish_reason ?? null;
280
+ let completion = content;
281
+ if (output_format) {
282
+ if (zodSchemaCandidate) {
283
+ const parsedJson = JSON.parse(content);
284
+ const output = output_format;
285
+ if (output &&
286
+ typeof output === 'object' &&
287
+ output.schema &&
288
+ typeof output.schema.parse === 'function') {
289
+ completion = output.schema.parse(parsedJson);
290
+ }
291
+ else {
292
+ completion = output.parse(parsedJson);
293
+ }
294
+ }
295
+ else {
296
+ completion = output_format.parse(content);
297
+ }
298
+ }
299
+ return new ChatInvokeCompletion(completion, usage, null, null, stopReason);
300
+ }
301
+ catch (error) {
302
+ if (error?.status === 429) {
303
+ throw new ModelRateLimitError(error?.message ?? 'Rate limit exceeded', 429, this.model);
304
+ }
305
+ throw new ModelProviderError(error?.message ?? String(error), error?.status ?? 500, this.model);
306
+ }
307
+ }
308
+ async invokeResponses(messages, output_format, zodSchemaCandidate, options) {
309
+ const serializer = new ResponsesAPIMessageSerializer();
310
+ const inputMessages = serializer.serialize(messages);
311
+ const request = {
32
312
  model: this.model,
33
- messages: openaiMessages,
34
- response_format: responseFormat,
35
- }, options.signal ? { signal: options.signal } : undefined);
36
- const content = response.choices[0].message.content || '';
37
- let completion = content;
38
- if (output_format) {
313
+ input: inputMessages,
314
+ ...this.getModelParamsForResponses(),
315
+ };
316
+ if (zodSchemaCandidate) {
39
317
  try {
40
- // Extract JSON from the response
41
- let jsonText = content.trim();
42
- // Handle markdown fenced code blocks
43
- const fencedMatch = jsonText.match(/```(?:json)?\s*([\s\S]*?)```/);
44
- if (fencedMatch && fencedMatch[1]) {
45
- jsonText = fencedMatch[1].trim();
318
+ const rawJsonSchema = zodSchemaToJsonSchema(zodSchemaCandidate, {
319
+ name: 'agent_output',
320
+ target: 'jsonSchema7',
321
+ });
322
+ const optimizedJsonSchema = SchemaOptimizer.createOptimizedJsonSchema(rawJsonSchema, {
323
+ removeMinItems: this.removeMinItemsFromSchema,
324
+ removeDefaults: this.removeDefaultsFromSchema,
325
+ });
326
+ if (this.addSchemaToSystemPrompt &&
327
+ inputMessages.length > 0 &&
328
+ inputMessages[0]?.role === 'system') {
329
+ const schemaText = `\n<json_schema>\n${JSON.stringify(optimizedJsonSchema)}\n</json_schema>`;
330
+ const firstInput = inputMessages[0];
331
+ const firstContent = firstInput?.content;
332
+ let patchedContent = firstContent ?? '';
333
+ if (typeof firstContent === 'string') {
334
+ patchedContent = firstContent + schemaText;
335
+ }
336
+ else if (Array.isArray(firstContent)) {
337
+ patchedContent = [
338
+ ...firstContent,
339
+ { type: 'input_text', text: schemaText },
340
+ ];
341
+ }
342
+ inputMessages[0] = {
343
+ ...inputMessages[0],
344
+ content: patchedContent,
345
+ };
346
+ request.input = inputMessages;
46
347
  }
47
- // Extract JSON object/array from the text
48
- const firstBrace = jsonText.indexOf('{');
49
- const firstBracket = jsonText.indexOf('[');
50
- const lastBrace = jsonText.lastIndexOf('}');
51
- const lastBracket = jsonText.lastIndexOf(']');
52
- // Determine if it's an object or array
53
- let startIdx = -1;
54
- let endIdx = -1;
55
- if (firstBrace !== -1 &&
56
- (firstBracket === -1 || firstBrace < firstBracket)) {
57
- // It's an object
58
- startIdx = firstBrace;
59
- endIdx = lastBrace;
348
+ if (!this.dontForceStructuredOutput) {
349
+ request.text = {
350
+ format: {
351
+ type: 'json_schema',
352
+ name: 'agent_output',
353
+ strict: true,
354
+ schema: optimizedJsonSchema,
355
+ },
356
+ };
60
357
  }
61
- else if (firstBracket !== -1) {
62
- // It's an array
63
- startIdx = firstBracket;
64
- endIdx = lastBracket;
358
+ }
359
+ catch {
360
+ // Skip structured output forcing when schema conversion fails.
361
+ }
362
+ }
363
+ try {
364
+ const response = await this.client.responses.create(request, options.signal ? { signal: options.signal } : undefined);
365
+ const content = this.getResponseOutputText(response);
366
+ const usage = this.getResponsesUsage(response);
367
+ const stopReason = response?.status ?? null;
368
+ let completion = content;
369
+ if (output_format) {
370
+ if (zodSchemaCandidate) {
371
+ const parsedJson = JSON.parse(content);
372
+ const output = output_format;
373
+ if (output &&
374
+ typeof output === 'object' &&
375
+ output.schema &&
376
+ typeof output.schema.parse === 'function') {
377
+ completion = output.schema.parse(parsedJson);
378
+ }
379
+ else {
380
+ completion = output.parse(parsedJson);
381
+ }
65
382
  }
66
- if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
67
- jsonText = jsonText.slice(startIdx, endIdx + 1);
383
+ else {
384
+ completion = output_format.parse(content);
68
385
  }
69
- const parsedJson = JSON.parse(jsonText);
70
- completion = output_format.parse(parsedJson);
71
386
  }
72
- catch (e) {
73
- console.error('Failed to parse Azure completion:', e);
74
- console.error('Raw content:', content.substring(0, 500));
75
- throw new Error(`Failed to parse LLM completion as JSON: ${e}`);
387
+ return new ChatInvokeCompletion(completion, usage, null, null, stopReason);
388
+ }
389
+ catch (error) {
390
+ if (error?.status === 429) {
391
+ throw new ModelRateLimitError(error?.message ?? 'Rate limit exceeded', 429, this.model);
76
392
  }
393
+ throw new ModelProviderError(error?.message ?? String(error), error?.status ?? 500, this.model);
77
394
  }
78
- return new ChatInvokeCompletion(completion, {
79
- prompt_tokens: response.usage?.prompt_tokens ?? 0,
80
- completion_tokens: response.usage?.completion_tokens ?? 0,
81
- total_tokens: response.usage?.total_tokens ?? 0,
82
- });
83
395
  }
84
396
  }
@@ -2,6 +2,8 @@ import type { ChatInvokeCompletion } from './views.js';
2
2
  import type { Message } from './messages.js';
3
3
  export interface ChatInvokeOptions {
4
4
  signal?: AbortSignal;
5
+ request_type?: string;
6
+ [key: string]: unknown;
5
7
  }
6
8
  export interface BaseChatModel {
7
9
  model: string;
@@ -0,0 +1,40 @@
1
+ import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
2
+ import type { Message } from '../messages.js';
3
+ import { ChatInvokeCompletion } from '../views.js';
4
+ export interface ChatBrowserUseOptions {
5
+ model?: string;
6
+ apiKey?: string;
7
+ baseUrl?: string;
8
+ timeout?: number;
9
+ maxRetries?: number;
10
+ retryBaseDelay?: number;
11
+ retryMaxDelay?: number;
12
+ fast?: boolean;
13
+ fetchImplementation?: typeof fetch;
14
+ }
15
+ export declare class ChatBrowserUse implements BaseChatModel {
16
+ model: string;
17
+ provider: string;
18
+ private readonly apiKey;
19
+ private readonly baseUrl;
20
+ private readonly timeoutMs;
21
+ private readonly maxRetries;
22
+ private readonly retryBaseDelay;
23
+ private readonly retryMaxDelay;
24
+ private readonly fast;
25
+ private readonly fetchImplementation;
26
+ constructor(options?: ChatBrowserUseOptions);
27
+ get name(): string;
28
+ get model_name(): string;
29
+ private getOutputSchema;
30
+ private parseOutput;
31
+ private serializeMessage;
32
+ private getUsage;
33
+ private raiseHttpError;
34
+ private isRetryableNetworkError;
35
+ private makeRequest;
36
+ ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
37
+ ainvoke<T>(messages: Message[], output_format: {
38
+ parse: (input: string) => T;
39
+ } | undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<T>>;
40
+ }