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,6 +1,25 @@
1
+ import { z } from 'zod';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
3
+ export const zodSchemaToJsonSchema = (schema, options = {}) => {
4
+ try {
5
+ const toJSONSchema = z?.toJSONSchema;
6
+ if (typeof toJSONSchema === 'function') {
7
+ const converted = toJSONSchema(schema);
8
+ if (converted && typeof converted === 'object') {
9
+ return converted;
10
+ }
11
+ }
12
+ }
13
+ catch {
14
+ // Fall back to zod-to-json-schema below.
15
+ }
16
+ return zodToJsonSchema(schema, options);
17
+ };
1
18
  export class SchemaOptimizer {
2
- static createOptimizedJsonSchema(schema) {
19
+ static createOptimizedJsonSchema(schema, options = {}) {
3
20
  const defsLookup = schema.$defs ?? {};
21
+ const removeMinItems = options.removeMinItems ?? false;
22
+ const removeDefaults = options.removeDefaults ?? false;
4
23
  const optimize = (obj, inProperties = false) => {
5
24
  if (Array.isArray(obj)) {
6
25
  return obj.map((item) => optimize(item, inProperties));
@@ -9,10 +28,18 @@ export class SchemaOptimizer {
9
28
  let flattenedRef = null;
10
29
  const optimized = {};
11
30
  for (const [key, value] of Object.entries(obj)) {
12
- if (key === '$defs' || key === 'additionalProperties')
31
+ if (key === '$defs')
32
+ continue;
33
+ // Some OpenAI-compatible providers reject this JSON Schema keyword.
34
+ if (key === 'propertyNames')
13
35
  continue;
14
36
  if (key === 'title' && !inProperties)
15
37
  continue;
38
+ if (removeMinItems && (key === 'minItems' || key === 'min_items')) {
39
+ continue;
40
+ }
41
+ if (removeDefaults && key === 'default')
42
+ continue;
16
43
  if (key === '$ref' && typeof value === 'string') {
17
44
  const refName = value.split('/').pop();
18
45
  if (defsLookup[refName]) {
@@ -20,6 +47,19 @@ export class SchemaOptimizer {
20
47
  }
21
48
  continue;
22
49
  }
50
+ if (key === 'additionalProperties') {
51
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
52
+ const optimizedAdditional = optimize(value, inProperties);
53
+ optimized[key] =
54
+ Object.keys(optimizedAdditional).length === 0
55
+ ? true
56
+ : optimizedAdditional;
57
+ }
58
+ else {
59
+ optimized[key] = value;
60
+ }
61
+ continue;
62
+ }
23
63
  if (key === 'properties') {
24
64
  optimized[key] = optimize(value, true);
25
65
  continue;
@@ -33,8 +73,12 @@ export class SchemaOptimizer {
33
73
  const result = flattenedRef
34
74
  ? { ...flattenedRef, ...optimized }
35
75
  : optimized;
76
+ const hasExplicitProperties = result.properties &&
77
+ typeof result.properties === 'object' &&
78
+ !Array.isArray(result.properties);
36
79
  if (result.type === 'object' &&
37
- result.additionalProperties === undefined) {
80
+ result.additionalProperties === undefined &&
81
+ hasExplicitProperties) {
38
82
  result.additionalProperties = false;
39
83
  }
40
84
  return result;
@@ -48,16 +92,77 @@ export class SchemaOptimizer {
48
92
  return;
49
93
  }
50
94
  if (obj && typeof obj === 'object') {
51
- if (obj.type === 'object' && obj.additionalProperties === undefined) {
95
+ const hasExplicitProperties = obj.properties &&
96
+ typeof obj.properties === 'object' &&
97
+ !Array.isArray(obj.properties);
98
+ if (obj.type === 'object' &&
99
+ obj.additionalProperties === undefined &&
100
+ hasExplicitProperties) {
52
101
  obj.additionalProperties = false;
53
102
  }
54
103
  Object.values(obj).forEach(ensureAdditionalProperties);
55
104
  }
56
105
  };
106
+ const stripStructuredDoneSuccess = (obj) => {
107
+ if (Array.isArray(obj)) {
108
+ obj.forEach(stripStructuredDoneSuccess);
109
+ return;
110
+ }
111
+ if (!obj || typeof obj !== 'object') {
112
+ return;
113
+ }
114
+ const properties = obj.properties;
115
+ if (obj.type === 'object' &&
116
+ properties &&
117
+ typeof properties === 'object' &&
118
+ !Array.isArray(properties)) {
119
+ const dataSchema = properties.data;
120
+ const successSchema = properties.success;
121
+ const looksLikeStructuredDone = dataSchema &&
122
+ successSchema &&
123
+ successSchema.type === 'boolean' &&
124
+ successSchema.description ===
125
+ 'True if user_request completed successfully';
126
+ if (looksLikeStructuredDone) {
127
+ delete properties.success;
128
+ if (Array.isArray(obj.required)) {
129
+ obj.required = obj.required.filter((name) => name !== 'success');
130
+ }
131
+ }
132
+ }
133
+ Object.values(obj).forEach(stripStructuredDoneSuccess);
134
+ };
135
+ const stripExtractOutputSchema = (obj, parentKey = null) => {
136
+ if (Array.isArray(obj)) {
137
+ obj.forEach((item) => stripExtractOutputSchema(item, parentKey));
138
+ return;
139
+ }
140
+ if (!obj || typeof obj !== 'object') {
141
+ return;
142
+ }
143
+ const isExtractActionSchema = parentKey === 'extract_structured_data' || parentKey === 'extract';
144
+ if (isExtractActionSchema && obj.type === 'object') {
145
+ const props = obj.properties;
146
+ if (props && typeof props === 'object' && !Array.isArray(props)) {
147
+ delete props.output_schema;
148
+ }
149
+ if (Array.isArray(obj.required)) {
150
+ obj.required = obj.required.filter((name) => name !== 'output_schema');
151
+ }
152
+ }
153
+ for (const [key, value] of Object.entries(obj)) {
154
+ stripExtractOutputSchema(value, key);
155
+ }
156
+ };
57
157
  ensureAdditionalProperties(optimizedSchema);
158
+ stripStructuredDoneSuccess(optimizedSchema);
159
+ stripExtractOutputSchema(optimizedSchema);
58
160
  SchemaOptimizer.makeStrictCompatible(optimizedSchema);
59
161
  return optimizedSchema;
60
162
  }
163
+ static createGeminiOptimizedSchema(schema) {
164
+ return SchemaOptimizer.createOptimizedJsonSchema(schema);
165
+ }
61
166
  static makeStrictCompatible(schema) {
62
167
  if (Array.isArray(schema)) {
63
168
  schema.forEach(SchemaOptimizer.makeStrictCompatible);
@@ -0,0 +1,50 @@
1
+ import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
2
+ import type { Message } from '../messages.js';
3
+ import { ChatInvokeCompletion } from '../views.js';
4
+ export interface ChatVercelOptions {
5
+ model?: string;
6
+ apiKey?: string;
7
+ baseURL?: string;
8
+ timeout?: number | null;
9
+ temperature?: number | null;
10
+ maxTokens?: number | null;
11
+ topP?: number | null;
12
+ seed?: number | null;
13
+ maxRetries?: number;
14
+ defaultHeaders?: Record<string, string> | null;
15
+ defaultQuery?: Record<string, string | undefined> | null;
16
+ fetchImplementation?: typeof fetch;
17
+ fetchOptions?: RequestInit | null;
18
+ reasoningModels?: string[] | null;
19
+ providerOptions?: Record<string, unknown> | null;
20
+ extraBody?: Record<string, unknown> | null;
21
+ removeMinItemsFromSchema?: boolean;
22
+ removeDefaultsFromSchema?: boolean;
23
+ }
24
+ export declare class ChatVercel implements BaseChatModel {
25
+ model: string;
26
+ provider: string;
27
+ private client;
28
+ private temperature;
29
+ private maxTokens;
30
+ private topP;
31
+ private seed;
32
+ private reasoningModels;
33
+ private providerOptions;
34
+ private extraBody;
35
+ private removeMinItemsFromSchema;
36
+ private removeDefaultsFromSchema;
37
+ constructor(options?: string | ChatVercelOptions);
38
+ get name(): string;
39
+ get model_name(): string;
40
+ private getUsage;
41
+ private getExtraBodyPayload;
42
+ private cloneMessages;
43
+ private appendJsonInstructionToMessages;
44
+ private parseStructuredJson;
45
+ private parseOutput;
46
+ ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
47
+ ainvoke<T>(messages: Message[], output_format: {
48
+ parse: (input: string) => T;
49
+ } | undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<T>>;
50
+ }
@@ -0,0 +1,276 @@
1
+ import OpenAI from 'openai';
2
+ import { ModelProviderError, ModelRateLimitError } from '../exceptions.js';
3
+ import { SchemaOptimizer, zodSchemaToJsonSchema } from '../schema.js';
4
+ import { ChatInvokeCompletion } from '../views.js';
5
+ import { VercelMessageSerializer } from './serializer.js';
6
+ const DEFAULT_REASONING_MODELS = [
7
+ 'o1',
8
+ 'o3',
9
+ 'o4',
10
+ 'gpt-oss',
11
+ 'deepseek-r1',
12
+ 'qwen3-next-80b-a3b-thinking',
13
+ ];
14
+ export class ChatVercel {
15
+ model;
16
+ provider = 'vercel';
17
+ client;
18
+ temperature;
19
+ maxTokens;
20
+ topP;
21
+ seed;
22
+ reasoningModels;
23
+ providerOptions;
24
+ extraBody;
25
+ removeMinItemsFromSchema;
26
+ removeDefaultsFromSchema;
27
+ constructor(options = {}) {
28
+ const normalizedOptions = typeof options === 'string' ? { model: options } : options;
29
+ const { model = 'openai/gpt-4o', apiKey = process.env.VERCEL_API_KEY, baseURL = process.env.VERCEL_BASE_URL ||
30
+ 'https://ai-gateway.vercel.sh/v1', timeout = null, temperature = null, maxTokens = null, topP = null, seed = null, maxRetries = 5, defaultHeaders = null, defaultQuery = null, fetchImplementation, fetchOptions = null, reasoningModels = [...DEFAULT_REASONING_MODELS], providerOptions = null, extraBody = null, removeMinItemsFromSchema = false, removeDefaultsFromSchema = false, } = normalizedOptions;
31
+ this.model = model;
32
+ this.temperature = temperature;
33
+ this.maxTokens = maxTokens;
34
+ this.topP = topP;
35
+ this.seed = seed;
36
+ this.reasoningModels = reasoningModels ? [...reasoningModels] : null;
37
+ this.providerOptions = providerOptions;
38
+ this.extraBody = extraBody;
39
+ this.removeMinItemsFromSchema = removeMinItemsFromSchema;
40
+ this.removeDefaultsFromSchema = removeDefaultsFromSchema;
41
+ this.client = new OpenAI({
42
+ apiKey,
43
+ baseURL,
44
+ timeout: timeout ?? undefined,
45
+ maxRetries,
46
+ defaultHeaders: defaultHeaders ?? undefined,
47
+ defaultQuery: defaultQuery ?? undefined,
48
+ fetch: fetchImplementation,
49
+ fetchOptions: (fetchOptions ?? undefined),
50
+ });
51
+ }
52
+ get name() {
53
+ return this.model;
54
+ }
55
+ get model_name() {
56
+ return this.model;
57
+ }
58
+ getUsage(response) {
59
+ if (!response.usage) {
60
+ return null;
61
+ }
62
+ return {
63
+ prompt_tokens: response.usage.prompt_tokens,
64
+ prompt_cached_tokens: response.usage.prompt_tokens_details?.cached_tokens ?? null,
65
+ prompt_cache_creation_tokens: null,
66
+ prompt_image_tokens: null,
67
+ completion_tokens: response.usage.completion_tokens,
68
+ total_tokens: response.usage.total_tokens,
69
+ };
70
+ }
71
+ getExtraBodyPayload() {
72
+ const payload = {
73
+ ...(this.extraBody ?? {}),
74
+ };
75
+ if (this.providerOptions) {
76
+ payload.providerOptions = this.providerOptions;
77
+ }
78
+ return Object.keys(payload).length > 0 ? payload : undefined;
79
+ }
80
+ cloneMessages(messages) {
81
+ return messages.map((message) => ({
82
+ ...message,
83
+ content: Array.isArray(message?.content)
84
+ ? message.content.map((part) => ({ ...part }))
85
+ : message?.content,
86
+ }));
87
+ }
88
+ appendJsonInstructionToMessages(messages, schema) {
89
+ const cloned = this.cloneMessages(messages);
90
+ const instruction = '\n\nIMPORTANT: You must respond with ONLY a valid JSON object ' +
91
+ '(no markdown, no code blocks, no explanations) that exactly matches this schema:\n' +
92
+ `${JSON.stringify(schema, null, 2)}`;
93
+ if (cloned.length > 0 && cloned[0]?.role === 'system') {
94
+ if (typeof cloned[0].content === 'string') {
95
+ cloned[0].content = `${cloned[0].content}${instruction}`;
96
+ }
97
+ else if (Array.isArray(cloned[0].content)) {
98
+ cloned[0].content = [
99
+ ...cloned[0].content,
100
+ { type: 'text', text: instruction },
101
+ ];
102
+ }
103
+ else {
104
+ cloned[0].content = instruction;
105
+ }
106
+ return cloned;
107
+ }
108
+ for (let i = cloned.length - 1; i >= 0; i -= 1) {
109
+ if (cloned[i]?.role === 'user') {
110
+ if (typeof cloned[i].content === 'string') {
111
+ cloned[i].content = `${cloned[i].content}${instruction}`;
112
+ }
113
+ else if (Array.isArray(cloned[i].content)) {
114
+ cloned[i].content = [
115
+ ...cloned[i].content,
116
+ { type: 'text', text: instruction },
117
+ ];
118
+ }
119
+ else {
120
+ cloned[i].content = instruction;
121
+ }
122
+ return cloned;
123
+ }
124
+ }
125
+ cloned.unshift({
126
+ role: 'system',
127
+ content: instruction,
128
+ });
129
+ return cloned;
130
+ }
131
+ parseStructuredJson(text) {
132
+ let jsonText = String(text ?? '').trim();
133
+ if (jsonText.startsWith('```json') && jsonText.endsWith('```')) {
134
+ jsonText = jsonText.slice(7, -3).trim();
135
+ }
136
+ else if (jsonText.startsWith('```') && jsonText.endsWith('```')) {
137
+ jsonText = jsonText.slice(3, -3).trim();
138
+ }
139
+ return JSON.parse(jsonText);
140
+ }
141
+ parseOutput(output_format, payload) {
142
+ const output = output_format;
143
+ if (output &&
144
+ typeof output === 'object' &&
145
+ output.schema &&
146
+ typeof output.schema.parse === 'function') {
147
+ return output.schema.parse(payload);
148
+ }
149
+ return output.parse(payload);
150
+ }
151
+ async ainvoke(messages, output_format, options = {}) {
152
+ const serializer = new VercelMessageSerializer();
153
+ const vercelMessages = serializer.serialize(messages);
154
+ const modelParams = {};
155
+ if (this.temperature !== null) {
156
+ modelParams.temperature = this.temperature;
157
+ }
158
+ if (this.maxTokens !== null) {
159
+ modelParams.max_tokens = this.maxTokens;
160
+ }
161
+ if (this.topP !== null) {
162
+ modelParams.top_p = this.topP;
163
+ }
164
+ if (this.seed !== null) {
165
+ modelParams.seed = this.seed;
166
+ }
167
+ const zodSchemaCandidate = (() => {
168
+ const output = output_format;
169
+ if (output &&
170
+ typeof output === 'object' &&
171
+ typeof output.safeParse === 'function' &&
172
+ typeof output.parse === 'function') {
173
+ return output;
174
+ }
175
+ if (output &&
176
+ typeof output === 'object' &&
177
+ output.schema &&
178
+ typeof output.schema.safeParse === 'function' &&
179
+ typeof output.schema.parse === 'function') {
180
+ return output.schema;
181
+ }
182
+ return null;
183
+ })();
184
+ const extraBodyPayload = this.getExtraBodyPayload();
185
+ const isGoogleModel = this.model.startsWith('google/');
186
+ const isAnthropicModel = this.model.startsWith('anthropic/');
187
+ const isReasoningModel = (this.reasoningModels ?? []).some((pattern) => String(this.model).toLowerCase().includes(String(pattern).toLowerCase()));
188
+ if (output_format &&
189
+ zodSchemaCandidate &&
190
+ (isGoogleModel || isAnthropicModel || isReasoningModel)) {
191
+ try {
192
+ const rawJsonSchema = zodSchemaToJsonSchema(zodSchemaCandidate, {
193
+ name: 'agent_output',
194
+ target: 'jsonSchema7',
195
+ });
196
+ const optimizedJsonSchema = SchemaOptimizer.createGeminiOptimizedSchema(rawJsonSchema);
197
+ const requestMessages = this.appendJsonInstructionToMessages(vercelMessages, optimizedJsonSchema);
198
+ const request = {
199
+ model: this.model,
200
+ messages: requestMessages,
201
+ ...modelParams,
202
+ };
203
+ if (extraBodyPayload) {
204
+ request.extra_body = extraBodyPayload;
205
+ }
206
+ const response = await this.client.chat.completions.create(request, options.signal ? { signal: options.signal } : undefined);
207
+ const content = response.choices[0].message.content || '';
208
+ const usage = this.getUsage(response);
209
+ const stopReason = response.choices[0].finish_reason ?? null;
210
+ const completion = this.parseOutput(output_format, this.parseStructuredJson(content));
211
+ return new ChatInvokeCompletion(completion, usage, null, null, stopReason);
212
+ }
213
+ catch (error) {
214
+ throw new ModelProviderError(`Failed to parse JSON response: ${error?.message ?? String(error)}`, 500, this.model);
215
+ }
216
+ }
217
+ let responseFormat = undefined;
218
+ if (zodSchemaCandidate) {
219
+ try {
220
+ const rawJsonSchema = zodSchemaToJsonSchema(zodSchemaCandidate, {
221
+ name: 'agent_output',
222
+ target: 'jsonSchema7',
223
+ });
224
+ const optimizedJsonSchema = SchemaOptimizer.createOptimizedJsonSchema(rawJsonSchema, {
225
+ removeMinItems: this.removeMinItemsFromSchema,
226
+ removeDefaults: this.removeDefaultsFromSchema,
227
+ });
228
+ responseFormat = {
229
+ type: 'json_schema',
230
+ json_schema: {
231
+ name: 'agent_output',
232
+ schema: optimizedJsonSchema,
233
+ strict: true,
234
+ },
235
+ };
236
+ }
237
+ catch {
238
+ responseFormat = undefined;
239
+ }
240
+ }
241
+ const request = {
242
+ model: this.model,
243
+ messages: vercelMessages,
244
+ response_format: responseFormat,
245
+ ...modelParams,
246
+ };
247
+ if (extraBodyPayload) {
248
+ request.extra_body = extraBodyPayload;
249
+ }
250
+ try {
251
+ const response = await this.client.chat.completions.create(request, options.signal ? { signal: options.signal } : undefined);
252
+ const content = response.choices[0].message.content || '';
253
+ const usage = this.getUsage(response);
254
+ const stopReason = response.choices[0].finish_reason ?? null;
255
+ let completion = content;
256
+ if (output_format) {
257
+ if (zodSchemaCandidate) {
258
+ completion = this.parseOutput(output_format, JSON.parse(content));
259
+ }
260
+ else {
261
+ completion = this.parseOutput(output_format, content);
262
+ }
263
+ }
264
+ return new ChatInvokeCompletion(completion, usage, null, null, stopReason);
265
+ }
266
+ catch (error) {
267
+ if (error?.status === 429) {
268
+ throw new ModelRateLimitError(error?.message ?? 'Rate limit exceeded', 429, this.model);
269
+ }
270
+ if (error?.status >= 500) {
271
+ throw new ModelProviderError(error?.message ?? 'Server error', error.status, this.model);
272
+ }
273
+ throw new ModelProviderError(error?.message ?? String(error), error?.status ?? 500, this.model);
274
+ }
275
+ }
276
+ }
@@ -0,0 +1 @@
1
+ export * from './chat.js';
@@ -0,0 +1 @@
1
+ export * from './chat.js';
@@ -0,0 +1,5 @@
1
+ import type { ChatCompletionMessageParam } from 'openai/resources/index.mjs';
2
+ import type { Message } from '../messages.js';
3
+ export declare class VercelMessageSerializer {
4
+ serialize(messages: Message[]): ChatCompletionMessageParam[];
5
+ }
@@ -0,0 +1,7 @@
1
+ import { OpenAIMessageSerializer } from '../openai/serializer.js';
2
+ export class VercelMessageSerializer {
3
+ serialize(messages) {
4
+ const serializer = new OpenAIMessageSerializer();
5
+ return serializer.serialize(messages);
6
+ }
7
+ }
@@ -11,5 +11,6 @@ export declare class ChatInvokeCompletion<T = string> {
11
11
  usage: ChatInvokeUsage | null;
12
12
  thinking: string | null;
13
13
  redacted_thinking: string | null;
14
- constructor(completion: T, usage?: ChatInvokeUsage | null, thinking?: string | null, redacted_thinking?: string | null);
14
+ stop_reason: string | null;
15
+ constructor(completion: T, usage?: ChatInvokeUsage | null, thinking?: string | null, redacted_thinking?: string | null, stop_reason?: string | null);
15
16
  }
package/dist/llm/views.js CHANGED
@@ -3,10 +3,12 @@ export class ChatInvokeCompletion {
3
3
  usage;
4
4
  thinking;
5
5
  redacted_thinking;
6
- constructor(completion, usage = null, thinking = null, redacted_thinking = null) {
6
+ stop_reason;
7
+ constructor(completion, usage = null, thinking = null, redacted_thinking = null, stop_reason = null) {
7
8
  this.completion = completion;
8
9
  this.usage = usage;
9
10
  this.thinking = thinking;
10
11
  this.redacted_thinking = redacted_thinking;
12
+ this.stop_reason = stop_reason;
11
13
  }
12
14
  }
@@ -4,6 +4,8 @@ interface SetupLoggingOptions {
4
4
  stream?: Writable;
5
5
  logLevel?: LogLevel;
6
6
  forceSetup?: boolean;
7
+ debugLogFile?: string | null;
8
+ infoLogFile?: string | null;
7
9
  }
8
10
  export declare class Logger {
9
11
  private readonly name;