browser-use 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +761 -0
  3. package/dist/agent/cloud-events.d.ts +264 -0
  4. package/dist/agent/cloud-events.js +318 -0
  5. package/dist/agent/gif.d.ts +15 -0
  6. package/dist/agent/gif.js +215 -0
  7. package/dist/agent/index.d.ts +8 -0
  8. package/dist/agent/index.js +8 -0
  9. package/dist/agent/message-manager/service.d.ts +30 -0
  10. package/dist/agent/message-manager/service.js +208 -0
  11. package/dist/agent/message-manager/utils.d.ts +2 -0
  12. package/dist/agent/message-manager/utils.js +41 -0
  13. package/dist/agent/message-manager/views.d.ts +26 -0
  14. package/dist/agent/message-manager/views.js +73 -0
  15. package/dist/agent/prompts.d.ts +52 -0
  16. package/dist/agent/prompts.js +259 -0
  17. package/dist/agent/service.d.ts +290 -0
  18. package/dist/agent/service.js +2200 -0
  19. package/dist/agent/views.d.ts +741 -0
  20. package/dist/agent/views.js +537 -0
  21. package/dist/browser/browser.d.ts +7 -0
  22. package/dist/browser/browser.js +5 -0
  23. package/dist/browser/context.d.ts +8 -0
  24. package/dist/browser/context.js +4 -0
  25. package/dist/browser/dvd-screensaver.d.ts +101 -0
  26. package/dist/browser/dvd-screensaver.js +270 -0
  27. package/dist/browser/extensions.d.ts +63 -0
  28. package/dist/browser/extensions.js +359 -0
  29. package/dist/browser/index.d.ts +10 -0
  30. package/dist/browser/index.js +9 -0
  31. package/dist/browser/playwright-manager.d.ts +47 -0
  32. package/dist/browser/playwright-manager.js +146 -0
  33. package/dist/browser/profile.d.ts +196 -0
  34. package/dist/browser/profile.js +815 -0
  35. package/dist/browser/session.d.ts +505 -0
  36. package/dist/browser/session.js +3409 -0
  37. package/dist/browser/types.d.ts +1184 -0
  38. package/dist/browser/types.js +1 -0
  39. package/dist/browser/utils.d.ts +1 -0
  40. package/dist/browser/utils.js +19 -0
  41. package/dist/browser/views.d.ts +78 -0
  42. package/dist/browser/views.js +72 -0
  43. package/dist/cli.d.ts +2 -0
  44. package/dist/cli.js +44 -0
  45. package/dist/config.d.ts +108 -0
  46. package/dist/config.js +430 -0
  47. package/dist/controller/index.d.ts +3 -0
  48. package/dist/controller/index.js +3 -0
  49. package/dist/controller/registry/index.d.ts +2 -0
  50. package/dist/controller/registry/index.js +2 -0
  51. package/dist/controller/registry/service.d.ts +45 -0
  52. package/dist/controller/registry/service.js +184 -0
  53. package/dist/controller/registry/views.d.ts +55 -0
  54. package/dist/controller/registry/views.js +174 -0
  55. package/dist/controller/service.d.ts +49 -0
  56. package/dist/controller/service.js +1176 -0
  57. package/dist/controller/views.d.ts +241 -0
  58. package/dist/controller/views.js +88 -0
  59. package/dist/dom/clickable-element-processor/service.d.ts +11 -0
  60. package/dist/dom/clickable-element-processor/service.js +60 -0
  61. package/dist/dom/dom_tree/index.js +1400 -0
  62. package/dist/dom/history-tree-processor/service.d.ts +14 -0
  63. package/dist/dom/history-tree-processor/service.js +75 -0
  64. package/dist/dom/history-tree-processor/view.d.ts +54 -0
  65. package/dist/dom/history-tree-processor/view.js +56 -0
  66. package/dist/dom/playground/extraction.d.ts +19 -0
  67. package/dist/dom/playground/extraction.js +187 -0
  68. package/dist/dom/playground/process-dom.d.ts +1 -0
  69. package/dist/dom/playground/process-dom.js +5 -0
  70. package/dist/dom/playground/test-accessibility.d.ts +44 -0
  71. package/dist/dom/playground/test-accessibility.js +111 -0
  72. package/dist/dom/service.d.ts +19 -0
  73. package/dist/dom/service.js +227 -0
  74. package/dist/dom/utils.d.ts +1 -0
  75. package/dist/dom/utils.js +6 -0
  76. package/dist/dom/views.d.ts +61 -0
  77. package/dist/dom/views.js +247 -0
  78. package/dist/event-bus.d.ts +11 -0
  79. package/dist/event-bus.js +19 -0
  80. package/dist/exceptions.d.ts +10 -0
  81. package/dist/exceptions.js +22 -0
  82. package/dist/filesystem/file-system.d.ts +68 -0
  83. package/dist/filesystem/file-system.js +412 -0
  84. package/dist/filesystem/index.d.ts +1 -0
  85. package/dist/filesystem/index.js +1 -0
  86. package/dist/index.d.ts +31 -0
  87. package/dist/index.js +33 -0
  88. package/dist/integrations/gmail/actions.d.ts +12 -0
  89. package/dist/integrations/gmail/actions.js +113 -0
  90. package/dist/integrations/gmail/index.d.ts +2 -0
  91. package/dist/integrations/gmail/index.js +2 -0
  92. package/dist/integrations/gmail/service.d.ts +61 -0
  93. package/dist/integrations/gmail/service.js +260 -0
  94. package/dist/llm/anthropic/chat.d.ts +28 -0
  95. package/dist/llm/anthropic/chat.js +126 -0
  96. package/dist/llm/anthropic/index.d.ts +2 -0
  97. package/dist/llm/anthropic/index.js +2 -0
  98. package/dist/llm/anthropic/serializer.d.ts +68 -0
  99. package/dist/llm/anthropic/serializer.js +285 -0
  100. package/dist/llm/aws/chat-anthropic.d.ts +61 -0
  101. package/dist/llm/aws/chat-anthropic.js +176 -0
  102. package/dist/llm/aws/chat-bedrock.d.ts +15 -0
  103. package/dist/llm/aws/chat-bedrock.js +80 -0
  104. package/dist/llm/aws/index.d.ts +3 -0
  105. package/dist/llm/aws/index.js +3 -0
  106. package/dist/llm/aws/serializer.d.ts +5 -0
  107. package/dist/llm/aws/serializer.js +68 -0
  108. package/dist/llm/azure/chat.d.ts +15 -0
  109. package/dist/llm/azure/chat.js +83 -0
  110. package/dist/llm/azure/index.d.ts +1 -0
  111. package/dist/llm/azure/index.js +1 -0
  112. package/dist/llm/base.d.ts +16 -0
  113. package/dist/llm/base.js +1 -0
  114. package/dist/llm/deepseek/chat.d.ts +15 -0
  115. package/dist/llm/deepseek/chat.js +51 -0
  116. package/dist/llm/deepseek/index.d.ts +2 -0
  117. package/dist/llm/deepseek/index.js +2 -0
  118. package/dist/llm/deepseek/serializer.d.ts +6 -0
  119. package/dist/llm/deepseek/serializer.js +57 -0
  120. package/dist/llm/exceptions.d.ts +10 -0
  121. package/dist/llm/exceptions.js +18 -0
  122. package/dist/llm/google/chat.d.ts +20 -0
  123. package/dist/llm/google/chat.js +144 -0
  124. package/dist/llm/google/index.d.ts +2 -0
  125. package/dist/llm/google/index.js +2 -0
  126. package/dist/llm/google/serializer.d.ts +6 -0
  127. package/dist/llm/google/serializer.js +64 -0
  128. package/dist/llm/groq/chat.d.ts +15 -0
  129. package/dist/llm/groq/chat.js +52 -0
  130. package/dist/llm/groq/index.d.ts +3 -0
  131. package/dist/llm/groq/index.js +3 -0
  132. package/dist/llm/groq/parser.d.ts +32 -0
  133. package/dist/llm/groq/parser.js +189 -0
  134. package/dist/llm/groq/serializer.d.ts +6 -0
  135. package/dist/llm/groq/serializer.js +56 -0
  136. package/dist/llm/messages.d.ts +77 -0
  137. package/dist/llm/messages.js +157 -0
  138. package/dist/llm/ollama/chat.d.ts +15 -0
  139. package/dist/llm/ollama/chat.js +77 -0
  140. package/dist/llm/ollama/index.d.ts +2 -0
  141. package/dist/llm/ollama/index.js +2 -0
  142. package/dist/llm/ollama/serializer.d.ts +6 -0
  143. package/dist/llm/ollama/serializer.js +53 -0
  144. package/dist/llm/openai/chat.d.ts +38 -0
  145. package/dist/llm/openai/chat.js +174 -0
  146. package/dist/llm/openai/index.d.ts +3 -0
  147. package/dist/llm/openai/index.js +3 -0
  148. package/dist/llm/openai/like.d.ts +17 -0
  149. package/dist/llm/openai/like.js +19 -0
  150. package/dist/llm/openai/serializer.d.ts +6 -0
  151. package/dist/llm/openai/serializer.js +57 -0
  152. package/dist/llm/openrouter/chat.d.ts +15 -0
  153. package/dist/llm/openrouter/chat.js +74 -0
  154. package/dist/llm/openrouter/index.d.ts +2 -0
  155. package/dist/llm/openrouter/index.js +2 -0
  156. package/dist/llm/openrouter/serializer.d.ts +3 -0
  157. package/dist/llm/openrouter/serializer.js +3 -0
  158. package/dist/llm/schema.d.ts +6 -0
  159. package/dist/llm/schema.js +77 -0
  160. package/dist/llm/views.d.ts +15 -0
  161. package/dist/llm/views.js +12 -0
  162. package/dist/logging-config.d.ts +25 -0
  163. package/dist/logging-config.js +89 -0
  164. package/dist/mcp/client.d.ts +142 -0
  165. package/dist/mcp/client.js +638 -0
  166. package/dist/mcp/controller.d.ts +6 -0
  167. package/dist/mcp/controller.js +38 -0
  168. package/dist/mcp/index.d.ts +3 -0
  169. package/dist/mcp/index.js +3 -0
  170. package/dist/mcp/server.d.ts +134 -0
  171. package/dist/mcp/server.js +759 -0
  172. package/dist/observability-decorators.d.ts +158 -0
  173. package/dist/observability-decorators.js +286 -0
  174. package/dist/observability.d.ts +23 -0
  175. package/dist/observability.js +58 -0
  176. package/dist/screenshots/index.d.ts +1 -0
  177. package/dist/screenshots/index.js +1 -0
  178. package/dist/screenshots/service.d.ts +6 -0
  179. package/dist/screenshots/service.js +28 -0
  180. package/dist/sync/auth.d.ts +27 -0
  181. package/dist/sync/auth.js +205 -0
  182. package/dist/sync/index.d.ts +2 -0
  183. package/dist/sync/index.js +2 -0
  184. package/dist/sync/service.d.ts +21 -0
  185. package/dist/sync/service.js +146 -0
  186. package/dist/telemetry/index.d.ts +2 -0
  187. package/dist/telemetry/index.js +2 -0
  188. package/dist/telemetry/service.d.ts +12 -0
  189. package/dist/telemetry/service.js +85 -0
  190. package/dist/telemetry/views.d.ts +112 -0
  191. package/dist/telemetry/views.js +112 -0
  192. package/dist/tokens/index.d.ts +2 -0
  193. package/dist/tokens/index.js +2 -0
  194. package/dist/tokens/service.d.ts +35 -0
  195. package/dist/tokens/service.js +423 -0
  196. package/dist/tokens/views.d.ts +58 -0
  197. package/dist/tokens/views.js +1 -0
  198. package/dist/utils.d.ts +128 -0
  199. package/dist/utils.js +529 -0
  200. package/package.json +94 -5
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Anthropic Message Serializer with Prompt Caching Support
3
+ *
4
+ * This serializer converts custom message types to Anthropic's MessageParam format
5
+ * and implements Anthropic's Prompt Caching feature to reduce costs by up to 90%.
6
+ *
7
+ * Caching Strategy:
8
+ * - Only the last message with cache=true will have cache_control enabled
9
+ * - Caching is most effective for system prompts and large conversation histories
10
+ * - Cache writes cost 25% more, but cache reads cost 90% less
11
+ *
12
+ * Example cost savings:
13
+ * - Without caching: 10,000 tokens @ $3/M = $0.030 per request
14
+ * - With caching (90% hit rate):
15
+ * - First request: 10,000 tokens @ $3.75/M (write) = $0.0375
16
+ * - Subsequent: 1,000 tokens @ $3/M + 9,000 tokens @ $0.30/M = $0.0057
17
+ * - Savings: 81% cost reduction
18
+ */
19
+ import { AssistantMessage, ContentPartImageParam, ContentPartTextParam, UserMessage, SystemMessage, } from '../messages.js';
20
+ export class AnthropicMessageSerializer {
21
+ /**
22
+ * Serialize a list of messages, extracting any system message
23
+ *
24
+ * @param messages - List of messages to serialize
25
+ * @returns Tuple of [messages, system_message]
26
+ */
27
+ serializeMessages(messages) {
28
+ // Make deep copies to avoid modifying originals
29
+ const messagesCopy = messages.map((m) => ({ ...m }));
30
+ // Separate system messages from normal messages
31
+ const normalMessages = [];
32
+ let systemMessage = null;
33
+ for (const message of messagesCopy) {
34
+ if (message instanceof SystemMessage) {
35
+ systemMessage = message;
36
+ }
37
+ else {
38
+ normalMessages.push(message);
39
+ }
40
+ }
41
+ // Clean cache messages so only the last cache=true message remains cached
42
+ const cleanedMessages = this._cleanCacheMessages(normalMessages);
43
+ // Serialize normal messages
44
+ const serializedMessages = cleanedMessages.map((msg) => this.serializeMessage(msg));
45
+ // Serialize system message
46
+ let serializedSystemMessage = undefined;
47
+ if (systemMessage) {
48
+ serializedSystemMessage = this._serializeContentToStr(systemMessage.content, systemMessage.cache);
49
+ }
50
+ return [serializedMessages, serializedSystemMessage];
51
+ }
52
+ /**
53
+ * Serialize a single message
54
+ */
55
+ serializeMessage(message) {
56
+ if (message instanceof UserMessage) {
57
+ return {
58
+ role: 'user',
59
+ content: Array.isArray(message.content)
60
+ ? message.content.map((part, idx, arr) => {
61
+ const isLastPart = idx === arr.length - 1;
62
+ const useCache = message.cache && isLastPart;
63
+ if (part instanceof ContentPartTextParam) {
64
+ return this._serializeContentPartText(part, useCache);
65
+ }
66
+ if (part instanceof ContentPartImageParam) {
67
+ return this._serializeContentPartImage(part);
68
+ }
69
+ return { type: 'text', text: '' };
70
+ })
71
+ : this._serializeContent(message.content, message.cache),
72
+ };
73
+ }
74
+ if (message instanceof AssistantMessage) {
75
+ const content = [];
76
+ // Add content blocks if present
77
+ if (message.content) {
78
+ if (typeof message.content === 'string') {
79
+ content.push({
80
+ type: 'text',
81
+ text: message.content,
82
+ ...(message.cache
83
+ ? { cache_control: this._serializeCacheControl(true) }
84
+ : {}),
85
+ });
86
+ }
87
+ else if (Array.isArray(message.content)) {
88
+ message.content.forEach((part, idx, arr) => {
89
+ const isLastPart = idx === arr.length - 1;
90
+ const useCache = message.cache && isLastPart && !message.tool_calls?.length;
91
+ if (part instanceof ContentPartTextParam) {
92
+ content.push(this._serializeContentPartText(part, useCache));
93
+ }
94
+ });
95
+ }
96
+ }
97
+ // Add tool use blocks if present
98
+ if (message.tool_calls) {
99
+ message.tool_calls.forEach((toolCall, idx, arr) => {
100
+ const isLastToolCall = idx === arr.length - 1;
101
+ const useCache = message.cache && isLastToolCall;
102
+ content.push({
103
+ type: 'tool_use',
104
+ id: toolCall.id,
105
+ name: toolCall.functionCall.name,
106
+ input: JSON.parse(toolCall.functionCall.arguments),
107
+ ...(useCache
108
+ ? { cache_control: this._serializeCacheControl(true) }
109
+ : {}),
110
+ });
111
+ });
112
+ }
113
+ // If no content or tool calls, add empty text block
114
+ if (!content.length) {
115
+ content.push({
116
+ type: 'text',
117
+ text: '',
118
+ ...(message.cache
119
+ ? { cache_control: this._serializeCacheControl(true) }
120
+ : {}),
121
+ });
122
+ }
123
+ return {
124
+ role: 'assistant',
125
+ content: content,
126
+ };
127
+ }
128
+ throw new Error(`Unknown message type or unhandled role: ${message.role}`);
129
+ }
130
+ /**
131
+ * Serialize cache control parameter
132
+ */
133
+ _serializeCacheControl(useCache) {
134
+ return useCache ? { type: 'ephemeral' } : undefined;
135
+ }
136
+ /**
137
+ * Serialize text content part with optional caching
138
+ */
139
+ _serializeContentPartText(part, useCache) {
140
+ return {
141
+ type: 'text',
142
+ text: part.text,
143
+ ...(useCache ? { cache_control: this._serializeCacheControl(true) } : {}),
144
+ };
145
+ }
146
+ /**
147
+ * Serialize image content part
148
+ */
149
+ _serializeContentPartImage(part) {
150
+ const url = part.image_url.url;
151
+ if (this._isBase64Image(url)) {
152
+ // Handle base64 encoded images
153
+ const [mediaType, data] = this._parseBase64Url(url);
154
+ return {
155
+ type: 'image',
156
+ source: {
157
+ type: 'base64',
158
+ media_type: mediaType,
159
+ data: data,
160
+ },
161
+ };
162
+ }
163
+ else {
164
+ // Handle URL images
165
+ return {
166
+ type: 'image',
167
+ source: {
168
+ type: 'url',
169
+ url: url,
170
+ },
171
+ };
172
+ }
173
+ }
174
+ /**
175
+ * Serialize content (string or array) with optional caching
176
+ */
177
+ _serializeContent(content, useCache) {
178
+ if (typeof content === 'string') {
179
+ if (useCache) {
180
+ return [
181
+ {
182
+ type: 'text',
183
+ text: content,
184
+ cache_control: this._serializeCacheControl(true),
185
+ },
186
+ ];
187
+ }
188
+ return content;
189
+ }
190
+ return content.map((part, idx, arr) => {
191
+ const isLastPart = idx === arr.length - 1;
192
+ const partUseCache = useCache && isLastPart;
193
+ if (part instanceof ContentPartTextParam) {
194
+ return this._serializeContentPartText(part, partUseCache);
195
+ }
196
+ else if (part instanceof ContentPartImageParam) {
197
+ return this._serializeContentPartImage(part);
198
+ }
199
+ return { type: 'text', text: '' };
200
+ });
201
+ }
202
+ /**
203
+ * Serialize content to string format (for system messages)
204
+ */
205
+ _serializeContentToStr(content, useCache) {
206
+ if (typeof content === 'string') {
207
+ if (useCache) {
208
+ return [
209
+ {
210
+ type: 'text',
211
+ text: content,
212
+ cache_control: this._serializeCacheControl(true),
213
+ },
214
+ ];
215
+ }
216
+ return content;
217
+ }
218
+ return content.map((part, idx, arr) => {
219
+ const isLastPart = idx === arr.length - 1;
220
+ const partUseCache = useCache && isLastPart;
221
+ return this._serializeContentPartText(part, partUseCache);
222
+ });
223
+ }
224
+ /**
225
+ * Check if URL is a base64 encoded image
226
+ */
227
+ _isBase64Image(url) {
228
+ return url.startsWith('data:image/');
229
+ }
230
+ /**
231
+ * Parse base64 data URL to extract media type and data
232
+ */
233
+ _parseBase64Url(url) {
234
+ if (!url.startsWith('data:')) {
235
+ throw new Error(`Invalid base64 URL: ${url}`);
236
+ }
237
+ const [header, data] = url.split(',', 2);
238
+ if (!header || !data) {
239
+ throw new Error(`Invalid base64 URL format: ${url}`);
240
+ }
241
+ let mediaType = header.split(';')[0]?.replace('data:', '') || 'image/png';
242
+ // Ensure it's a supported media type
243
+ const supportedTypes = [
244
+ 'image/jpeg',
245
+ 'image/png',
246
+ 'image/gif',
247
+ 'image/webp',
248
+ ];
249
+ if (!supportedTypes.includes(mediaType)) {
250
+ // Default to png if not recognized
251
+ mediaType = 'image/png';
252
+ }
253
+ return [mediaType, data];
254
+ }
255
+ /**
256
+ * Clean cache settings so only the last cache=true message remains cached
257
+ *
258
+ * Because of how Claude caching works, only the last cache message matters.
259
+ * This method automatically removes cache=True from all messages except the last one.
260
+ */
261
+ _cleanCacheMessages(messages) {
262
+ if (!messages.length) {
263
+ return messages;
264
+ }
265
+ // Create deep copies to avoid modifying originals
266
+ const cleanedMessages = messages.map((msg) => ({ ...msg }));
267
+ // Find the last message with cache=true
268
+ let lastCacheIndex = -1;
269
+ for (let i = cleanedMessages.length - 1; i >= 0; i--) {
270
+ if (cleanedMessages[i].cache) {
271
+ lastCacheIndex = i;
272
+ break;
273
+ }
274
+ }
275
+ // If we found a cached message, disable cache for all others
276
+ if (lastCacheIndex !== -1) {
277
+ for (let i = 0; i < cleanedMessages.length; i++) {
278
+ if (i !== lastCacheIndex && cleanedMessages[i].cache) {
279
+ cleanedMessages[i].cache = false;
280
+ }
281
+ }
282
+ }
283
+ return cleanedMessages;
284
+ }
285
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * AWS Bedrock Anthropic Claude chat model.
3
+ *
4
+ * This is a convenience class that provides Claude-specific defaults
5
+ * for the AWS Bedrock service. It inherits all functionality from
6
+ * ChatBedrockConverse but sets Anthropic Claude as the default model
7
+ * and uses the Anthropic message serializer for better compatibility.
8
+ *
9
+ * Usage:
10
+ * ```typescript
11
+ * import { ChatAnthropicBedrock } from './llm/aws/chat-anthropic.js';
12
+ *
13
+ * const llm = new ChatAnthropicBedrock({
14
+ * model: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
15
+ * region: 'us-east-1'
16
+ * });
17
+ *
18
+ * const response = await llm.ainvoke(messages);
19
+ * ```
20
+ */
21
+ import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
22
+ import { ChatInvokeCompletion } from '../views.js';
23
+ import { type Message } from '../messages.js';
24
+ export interface ChatAnthropicBedrockConfig {
25
+ /** Model ID, defaults to Claude 3.5 Sonnet */
26
+ model?: string;
27
+ /** AWS region, defaults to us-east-1 */
28
+ region?: string;
29
+ /** Maximum tokens to generate */
30
+ max_tokens?: number;
31
+ /** Temperature for sampling (0-1) */
32
+ temperature?: number | null;
33
+ /** Top-p sampling parameter */
34
+ top_p?: number | null;
35
+ /** Top-k sampling parameter */
36
+ top_k?: number | null;
37
+ /** Stop sequences */
38
+ stop_sequences?: string[] | null;
39
+ }
40
+ export declare class ChatAnthropicBedrock implements BaseChatModel {
41
+ model: string;
42
+ provider: string;
43
+ private client;
44
+ private max_tokens;
45
+ private temperature;
46
+ private top_p;
47
+ private top_k;
48
+ private stop_sequences;
49
+ constructor(config?: ChatAnthropicBedrockConfig);
50
+ get name(): string;
51
+ get model_name(): string;
52
+ private _getInferenceParams;
53
+ ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
54
+ ainvoke<T>(messages: Message[], output_format: {
55
+ parse: (input: string) => T;
56
+ }, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<T>>;
57
+ /**
58
+ * Simple Zod to JSON Schema conversion for structured output
59
+ */
60
+ private _zodToJsonSchema;
61
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * AWS Bedrock Anthropic Claude chat model.
3
+ *
4
+ * This is a convenience class that provides Claude-specific defaults
5
+ * for the AWS Bedrock service. It inherits all functionality from
6
+ * ChatBedrockConverse but sets Anthropic Claude as the default model
7
+ * and uses the Anthropic message serializer for better compatibility.
8
+ *
9
+ * Usage:
10
+ * ```typescript
11
+ * import { ChatAnthropicBedrock } from './llm/aws/chat-anthropic.js';
12
+ *
13
+ * const llm = new ChatAnthropicBedrock({
14
+ * model: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
15
+ * region: 'us-east-1'
16
+ * });
17
+ *
18
+ * const response = await llm.ainvoke(messages);
19
+ * ```
20
+ */
21
+ import { BedrockRuntimeClient, ConverseCommand, } from '@aws-sdk/client-bedrock-runtime';
22
+ import { ChatInvokeCompletion } from '../views.js';
23
+ import { AnthropicMessageSerializer } from '../anthropic/serializer.js';
24
+ export class ChatAnthropicBedrock {
25
+ model;
26
+ provider = 'anthropic_bedrock';
27
+ client;
28
+ max_tokens;
29
+ temperature;
30
+ top_p;
31
+ top_k;
32
+ stop_sequences;
33
+ constructor(config = {}) {
34
+ // Anthropic Claude specific defaults
35
+ this.model = config.model || 'anthropic.claude-3-5-sonnet-20241022-v2:0';
36
+ this.max_tokens = config.max_tokens || 8192;
37
+ this.temperature =
38
+ config.temperature === undefined ? null : config.temperature;
39
+ this.top_p = config.top_p === undefined ? null : config.top_p;
40
+ this.top_k = config.top_k === undefined ? null : config.top_k;
41
+ this.stop_sequences =
42
+ config.stop_sequences === undefined ? null : config.stop_sequences;
43
+ const region = config.region || process.env.AWS_REGION || 'us-east-1';
44
+ this.client = new BedrockRuntimeClient({ region });
45
+ }
46
+ get name() {
47
+ return this.model;
48
+ }
49
+ get model_name() {
50
+ return this.model;
51
+ }
52
+ _getInferenceParams() {
53
+ const params = {
54
+ maxTokens: this.max_tokens,
55
+ };
56
+ if (this.temperature !== null) {
57
+ params.temperature = this.temperature;
58
+ }
59
+ if (this.top_p !== null) {
60
+ params.topP = this.top_p;
61
+ }
62
+ if (this.stop_sequences !== null && this.stop_sequences.length > 0) {
63
+ params.stopSequences = this.stop_sequences;
64
+ }
65
+ return params;
66
+ }
67
+ async ainvoke(messages, output_format, options = {}) {
68
+ // Use Anthropic-specific message serializer
69
+ const serializer = new AnthropicMessageSerializer();
70
+ const [anthropicMessages, systemPrompt] = serializer.serializeMessages(messages);
71
+ // Convert Anthropic messages to Bedrock format
72
+ const bedrockMessages = anthropicMessages.map((msg) => {
73
+ const content = Array.isArray(msg.content)
74
+ ? msg.content.map((block) => {
75
+ if (block.type === 'text') {
76
+ return { text: block.text };
77
+ }
78
+ else if (block.type === 'image') {
79
+ // Handle image blocks if needed
80
+ return { text: '[Image]' };
81
+ }
82
+ return { text: String(block) };
83
+ })
84
+ : [{ text: msg.content }];
85
+ return {
86
+ role: msg.role,
87
+ content,
88
+ };
89
+ });
90
+ // Handle system message
91
+ const system = systemPrompt
92
+ ? [
93
+ {
94
+ text: typeof systemPrompt === 'string'
95
+ ? systemPrompt
96
+ : JSON.stringify(systemPrompt),
97
+ },
98
+ ]
99
+ : undefined;
100
+ let tools = undefined;
101
+ let toolConfig = undefined;
102
+ if (output_format && 'schema' in output_format) {
103
+ // Structured output using tools
104
+ try {
105
+ const schema = output_format.schema?.shape
106
+ ? this._zodToJsonSchema(output_format.schema)
107
+ : {};
108
+ tools = [
109
+ {
110
+ toolSpec: {
111
+ name: 'extract_structured_data',
112
+ description: 'Extract structured data from the response',
113
+ inputSchema: {
114
+ json: schema,
115
+ },
116
+ },
117
+ },
118
+ ];
119
+ toolConfig = {
120
+ tools: tools,
121
+ toolChoice: { tool: { name: 'extract_structured_data' } },
122
+ };
123
+ }
124
+ catch (e) {
125
+ console.warn('Failed to convert output_format to JSON schema', e);
126
+ }
127
+ }
128
+ const command = new ConverseCommand({
129
+ modelId: this.model,
130
+ messages: bedrockMessages,
131
+ system: system,
132
+ toolConfig: toolConfig,
133
+ inferenceConfig: this._getInferenceParams(),
134
+ });
135
+ const response = await this.client.send(command, options.signal ? { abortSignal: options.signal } : undefined);
136
+ let completion = '';
137
+ if (response.output?.message?.content) {
138
+ // Check for tool use (structured output)
139
+ const toolUseBlock = response.output.message.content.find((block) => block.toolUse);
140
+ if (toolUseBlock && toolUseBlock.toolUse && output_format) {
141
+ completion = output_format.parse(toolUseBlock.toolUse.input);
142
+ }
143
+ else {
144
+ // Fallback to text
145
+ const textBlock = response.output.message.content.find((block) => block.text);
146
+ completion = textBlock?.text || '';
147
+ }
148
+ }
149
+ return new ChatInvokeCompletion(completion, {
150
+ prompt_tokens: response.usage?.inputTokens ?? 0,
151
+ completion_tokens: response.usage?.outputTokens ?? 0,
152
+ total_tokens: response.usage?.totalTokens ?? 0,
153
+ });
154
+ }
155
+ /**
156
+ * Simple Zod to JSON Schema conversion for structured output
157
+ */
158
+ _zodToJsonSchema(schema) {
159
+ // This is a simplified version - you might want to use zod-to-json-schema package
160
+ try {
161
+ const { zodToJsonSchema } = require('zod-to-json-schema');
162
+ return zodToJsonSchema(schema, {
163
+ name: 'Response',
164
+ target: 'jsonSchema7',
165
+ });
166
+ }
167
+ catch {
168
+ // Fallback if zod-to-json-schema is not available
169
+ return {
170
+ type: 'object',
171
+ properties: {},
172
+ required: [],
173
+ };
174
+ }
175
+ }
176
+ }
@@ -0,0 +1,15 @@
1
+ import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
2
+ import { ChatInvokeCompletion } from '../views.js';
3
+ import { type Message } from '../messages.js';
4
+ export declare class ChatBedrockConverse implements BaseChatModel {
5
+ model: string;
6
+ provider: string;
7
+ private client;
8
+ constructor(model?: string, region?: string);
9
+ get name(): string;
10
+ get model_name(): string;
11
+ ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
12
+ ainvoke<T>(messages: Message[], output_format: {
13
+ parse: (input: string) => T;
14
+ } | undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<T>>;
15
+ }
@@ -0,0 +1,80 @@
1
+ import { BedrockRuntimeClient, ConverseCommand, } from '@aws-sdk/client-bedrock-runtime';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
3
+ import { ChatInvokeCompletion } from '../views.js';
4
+ import { SystemMessage } from '../messages.js';
5
+ import { AWSBedrockMessageSerializer } from './serializer.js';
6
+ export class ChatBedrockConverse {
7
+ model;
8
+ provider = 'aws';
9
+ client;
10
+ constructor(model = 'anthropic.claude-3-5-sonnet-20240620-v1:0', region = process.env.AWS_REGION || 'us-east-1') {
11
+ this.model = model;
12
+ this.client = new BedrockRuntimeClient({ region });
13
+ }
14
+ get name() {
15
+ return this.model;
16
+ }
17
+ get model_name() {
18
+ return this.model;
19
+ }
20
+ async ainvoke(messages, output_format, options = {}) {
21
+ const serializer = new AWSBedrockMessageSerializer();
22
+ const bedrockMessages = serializer.serialize(messages);
23
+ const systemMessage = messages.find((msg) => msg instanceof SystemMessage);
24
+ const system = systemMessage ? [{ text: systemMessage.text }] : undefined;
25
+ let tools = undefined;
26
+ let toolConfig = undefined;
27
+ if (output_format && 'schema' in output_format && output_format.schema) {
28
+ try {
29
+ const jsonSchema = zodToJsonSchema(output_format, {
30
+ name: 'Response',
31
+ target: 'jsonSchema7',
32
+ });
33
+ tools = [
34
+ {
35
+ toolSpec: {
36
+ name: 'response',
37
+ description: 'The response to the user request',
38
+ inputSchema: {
39
+ json: jsonSchema,
40
+ },
41
+ },
42
+ },
43
+ ];
44
+ toolConfig = {
45
+ tools: tools,
46
+ toolChoice: { tool: { name: 'response' } },
47
+ };
48
+ }
49
+ catch (e) {
50
+ console.warn('Failed to convert output_format to JSON schema for AWS Bedrock', e);
51
+ }
52
+ }
53
+ const command = new ConverseCommand({
54
+ modelId: this.model,
55
+ messages: bedrockMessages,
56
+ system: system,
57
+ toolConfig: toolConfig,
58
+ });
59
+ const response = await this.client.send(command, options.signal ? { abortSignal: options.signal } : undefined);
60
+ let completion = '';
61
+ if (response.output?.message?.content) {
62
+ // Check for tool use
63
+ const toolUseBlock = response.output.message.content.find((block) => block.toolUse);
64
+ if (toolUseBlock && toolUseBlock.toolUse && output_format) {
65
+ completion = output_format.parse(toolUseBlock.toolUse.input);
66
+ }
67
+ else {
68
+ // Fallback to text
69
+ const textBlock = response.output.message.content.find((block) => block.text);
70
+ completion = textBlock?.text || '';
71
+ }
72
+ }
73
+ const usage = response.usage || {};
74
+ return new ChatInvokeCompletion(completion, {
75
+ prompt_tokens: usage.inputTokens || 0,
76
+ completion_tokens: usage.outputTokens || 0,
77
+ total_tokens: usage.totalTokens || 0,
78
+ });
79
+ }
80
+ }
@@ -0,0 +1,3 @@
1
+ export * from './chat-bedrock.js';
2
+ export * from './chat-anthropic.js';
3
+ export * from './serializer.js';
@@ -0,0 +1,3 @@
1
+ export * from './chat-bedrock.js';
2
+ export * from './chat-anthropic.js';
3
+ export * from './serializer.js';
@@ -0,0 +1,5 @@
1
+ import { type Message } from '../messages.js';
2
+ export declare class AWSBedrockMessageSerializer {
3
+ serialize(messages: Message[]): any[];
4
+ private serializeMessage;
5
+ }