browser-use 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -686
- package/dist/actor/element.d.ts +19 -0
- package/dist/actor/element.js +46 -0
- package/dist/actor/index.d.ts +4 -0
- package/dist/actor/index.js +4 -0
- package/dist/actor/mouse.d.ts +19 -0
- package/dist/actor/mouse.js +39 -0
- package/dist/actor/page.d.ts +29 -0
- package/dist/actor/page.js +88 -0
- package/dist/actor/utils.d.ts +4 -0
- package/dist/actor/utils.js +35 -0
- package/dist/agent/cloud-events.d.ts +18 -0
- package/dist/agent/cloud-events.js +65 -2
- package/dist/agent/gif.d.ts +1 -0
- package/dist/agent/gif.js +24 -2
- package/dist/agent/judge.d.ts +17 -0
- package/dist/agent/judge.js +197 -0
- package/dist/agent/message-manager/service.d.ts +12 -4
- package/dist/agent/message-manager/service.js +205 -39
- package/dist/agent/message-manager/utils.js +0 -1
- package/dist/agent/message-manager/views.d.ts +4 -0
- package/dist/agent/message-manager/views.js +11 -7
- package/dist/agent/prompts.d.ts +24 -3
- package/dist/agent/prompts.js +274 -59
- package/dist/agent/service.d.ts +99 -41
- package/dist/agent/service.js +2266 -472
- package/dist/agent/variable-detector.d.ts +12 -0
- package/dist/agent/variable-detector.js +211 -0
- package/dist/agent/views.d.ts +237 -18
- package/dist/agent/views.js +446 -33
- package/dist/browser/cloud/cloud.d.ts +20 -0
- package/dist/browser/cloud/cloud.js +129 -0
- package/dist/browser/cloud/index.d.ts +2 -0
- package/dist/browser/cloud/index.js +2 -0
- package/dist/browser/cloud/views.d.ts +41 -0
- package/dist/browser/cloud/views.js +35 -0
- package/dist/browser/events.d.ts +345 -0
- package/dist/browser/events.js +566 -0
- package/dist/browser/extensions.js +17 -17
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +4 -0
- package/dist/browser/profile.d.ts +8 -2
- package/dist/browser/profile.js +79 -12
- package/dist/browser/session-manager.d.ts +85 -0
- package/dist/browser/session-manager.js +208 -0
- package/dist/browser/session.d.ts +100 -8
- package/dist/browser/session.js +1097 -58
- package/dist/browser/types.d.ts +0 -2
- package/dist/browser/views.d.ts +39 -0
- package/dist/browser/views.js +32 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
- package/dist/browser/watchdogs/base.d.ts +21 -0
- package/dist/browser/watchdogs/base.js +81 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
- package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
- package/dist/browser/watchdogs/crash-watchdog.js +296 -0
- package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
- package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
- package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/dom-watchdog.js +31 -0
- package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
- package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
- package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
- package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
- package/dist/browser/watchdogs/index.d.ts +15 -0
- package/dist/browser/watchdogs/index.js +15 -0
- package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
- package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
- package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
- package/dist/browser/watchdogs/popups-watchdog.js +77 -0
- package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
- package/dist/browser/watchdogs/recording-watchdog.js +249 -0
- package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
- package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
- package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/security-watchdog.js +84 -0
- package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
- package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
- package/dist/cli.d.ts +7 -2
- package/dist/cli.js +182 -25
- package/dist/code-use/formatting.d.ts +3 -0
- package/dist/code-use/formatting.js +18 -0
- package/dist/code-use/index.d.ts +6 -0
- package/dist/code-use/index.js +6 -0
- package/dist/code-use/namespace.d.ts +5 -0
- package/dist/code-use/namespace.js +81 -0
- package/dist/code-use/notebook-export.d.ts +3 -0
- package/dist/code-use/notebook-export.js +56 -0
- package/dist/code-use/service.d.ts +24 -0
- package/dist/code-use/service.js +104 -0
- package/dist/code-use/utils.d.ts +4 -0
- package/dist/code-use/utils.js +98 -0
- package/dist/code-use/views.d.ts +108 -0
- package/dist/code-use/views.js +165 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +69 -3
- package/dist/controller/registry/service.d.ts +10 -1
- package/dist/controller/registry/service.js +266 -10
- package/dist/controller/registry/views.d.ts +4 -1
- package/dist/controller/registry/views.js +25 -2
- package/dist/controller/service.d.ts +10 -1
- package/dist/controller/service.js +1807 -268
- package/dist/controller/views.d.ts +78 -155
- package/dist/controller/views.js +61 -12
- package/dist/dom/history-tree-processor/service.d.ts +5 -0
- package/dist/dom/history-tree-processor/service.js +169 -14
- package/dist/dom/history-tree-processor/view.d.ts +7 -1
- package/dist/dom/history-tree-processor/view.js +10 -1
- package/dist/dom/markdown-extractor.d.ts +37 -0
- package/dist/dom/markdown-extractor.js +345 -0
- package/dist/dom/service.d.ts +3 -1
- package/dist/dom/service.js +76 -0
- package/dist/dom/views.d.ts +1 -0
- package/dist/dom/views.js +45 -0
- package/dist/event-bus.d.ts +107 -7
- package/dist/event-bus.js +313 -10
- package/dist/exceptions.d.ts +0 -3
- package/dist/exceptions.js +0 -7
- package/dist/filesystem/file-system.d.ts +18 -0
- package/dist/filesystem/file-system.js +503 -42
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/integrations/gmail/actions.d.ts +3 -3
- package/dist/integrations/gmail/actions.js +4 -4
- package/dist/llm/anthropic/chat.d.ts +18 -1
- package/dist/llm/anthropic/chat.js +123 -55
- package/dist/llm/anthropic/serializer.d.ts +2 -0
- package/dist/llm/anthropic/serializer.js +81 -9
- package/dist/llm/aws/chat-anthropic.d.ts +17 -0
- package/dist/llm/aws/chat-anthropic.js +126 -26
- package/dist/llm/aws/chat-bedrock.d.ts +28 -1
- package/dist/llm/aws/chat-bedrock.js +161 -34
- package/dist/llm/aws/serializer.d.ts +13 -1
- package/dist/llm/aws/serializer.js +56 -17
- package/dist/llm/azure/chat.d.ts +53 -2
- package/dist/llm/azure/chat.js +366 -54
- package/dist/llm/base.d.ts +2 -0
- package/dist/llm/browser-use/chat.d.ts +40 -0
- package/dist/llm/browser-use/chat.js +305 -0
- package/dist/llm/browser-use/index.d.ts +1 -0
- package/dist/llm/browser-use/index.js +1 -0
- package/dist/llm/cerebras/chat.d.ts +39 -0
- package/dist/llm/cerebras/chat.js +178 -0
- package/dist/llm/cerebras/index.d.ts +2 -0
- package/dist/llm/cerebras/index.js +2 -0
- package/dist/llm/cerebras/serializer.d.ts +7 -0
- package/dist/llm/cerebras/serializer.js +82 -0
- package/dist/llm/deepseek/chat.d.ts +19 -2
- package/dist/llm/deepseek/chat.js +138 -25
- package/dist/llm/google/chat.d.ts +46 -2
- package/dist/llm/google/chat.js +267 -64
- package/dist/llm/google/serializer.d.ts +9 -1
- package/dist/llm/google/serializer.js +141 -34
- package/dist/llm/groq/chat.d.ts +21 -2
- package/dist/llm/groq/chat.js +125 -26
- package/dist/llm/groq/parser.js +3 -1
- package/dist/llm/mistral/chat.d.ts +43 -0
- package/dist/llm/mistral/chat.js +154 -0
- package/dist/llm/mistral/index.d.ts +2 -0
- package/dist/llm/mistral/index.js +2 -0
- package/dist/llm/mistral/schema.d.ts +8 -0
- package/dist/llm/mistral/schema.js +27 -0
- package/dist/llm/models.d.ts +2 -0
- package/dist/llm/models.js +317 -0
- package/dist/llm/ollama/chat.d.ts +13 -1
- package/dist/llm/ollama/chat.js +110 -19
- package/dist/llm/ollama/serializer.d.ts +1 -0
- package/dist/llm/ollama/serializer.js +34 -12
- package/dist/llm/openai/chat.d.ts +16 -0
- package/dist/llm/openai/chat.js +94 -44
- package/dist/llm/openai/like.d.ts +5 -3
- package/dist/llm/openai/like.js +7 -3
- package/dist/llm/openai/responses-serializer.d.ts +18 -0
- package/dist/llm/openai/responses-serializer.js +72 -0
- package/dist/llm/openrouter/chat.d.ts +28 -2
- package/dist/llm/openrouter/chat.js +115 -29
- package/dist/llm/schema.d.ts +11 -1
- package/dist/llm/schema.js +81 -1
- package/dist/llm/vercel/chat.d.ts +50 -0
- package/dist/llm/vercel/chat.js +276 -0
- package/dist/llm/vercel/index.d.ts +1 -0
- package/dist/llm/vercel/index.js +1 -0
- package/dist/llm/vercel/serializer.d.ts +5 -0
- package/dist/llm/vercel/serializer.js +7 -0
- package/dist/llm/views.d.ts +2 -1
- package/dist/llm/views.js +3 -1
- package/dist/logging-config.d.ts +2 -0
- package/dist/logging-config.js +82 -29
- package/dist/mcp/client.d.ts +10 -5
- package/dist/mcp/client.js +14 -9
- package/dist/mcp/controller.d.ts +42 -3
- package/dist/mcp/controller.js +56 -31
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.js +255 -52
- package/dist/observability.js +10 -4
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.js +2 -0
- package/dist/sandbox/sandbox.d.ts +19 -0
- package/dist/sandbox/sandbox.js +140 -0
- package/dist/sandbox/views.d.ts +67 -0
- package/dist/sandbox/views.js +121 -0
- package/dist/skill-cli/index.d.ts +3 -0
- package/dist/skill-cli/index.js +3 -0
- package/dist/skill-cli/protocol.d.ts +30 -0
- package/dist/skill-cli/protocol.js +48 -0
- package/dist/skill-cli/server.d.ts +11 -0
- package/dist/skill-cli/server.js +85 -0
- package/dist/skill-cli/sessions.d.ts +24 -0
- package/dist/skill-cli/sessions.js +47 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/service.d.ts +27 -0
- package/dist/skills/service.js +266 -0
- package/dist/skills/utils.d.ts +6 -0
- package/dist/skills/utils.js +53 -0
- package/dist/skills/views.d.ts +40 -0
- package/dist/skills/views.js +10 -0
- package/dist/sync/auth.js +8 -3
- package/dist/sync/service.d.ts +6 -6
- package/dist/sync/service.js +54 -89
- package/dist/telemetry/views.d.ts +20 -6
- package/dist/telemetry/views.js +23 -5
- package/dist/tokens/custom-pricing.d.ts +2 -0
- package/dist/tokens/custom-pricing.js +22 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/mappings.d.ts +1 -0
- package/dist/tokens/mappings.js +3 -0
- package/dist/tokens/service.js +27 -8
- package/dist/tools/extraction/index.d.ts +2 -0
- package/dist/tools/extraction/index.js +2 -0
- package/dist/tools/extraction/schema-utils.d.ts +6 -0
- package/dist/tools/extraction/schema-utils.js +237 -0
- package/dist/tools/extraction/views.d.ts +7 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/registry/index.d.ts +2 -0
- package/dist/tools/registry/index.js +2 -0
- package/dist/tools/registry/service.d.ts +1 -0
- package/dist/tools/registry/service.js +1 -0
- package/dist/tools/registry/views.d.ts +1 -0
- package/dist/tools/registry/views.js +1 -0
- package/dist/tools/service.d.ts +2 -0
- package/dist/tools/service.js +1 -0
- package/dist/tools/utils.d.ts +2 -0
- package/dist/tools/utils.js +57 -0
- package/dist/tools/views.d.ts +1 -0
- package/dist/tools/views.js +1 -0
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +70 -3
- package/package.json +87 -26
- package/dist/dom/playground/process-dom.js +0 -5
- package/dist/dom/playground/test-accessibility.d.ts +0 -44
- package/dist/dom/playground/test-accessibility.js +0 -111
- /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
import { BedrockRuntimeClient, ConverseCommand, } from '@aws-sdk/client-bedrock-runtime';
|
|
22
|
+
import { ModelProviderError, ModelRateLimitError } from '../exceptions.js';
|
|
22
23
|
import { ChatInvokeCompletion } from '../views.js';
|
|
23
24
|
import { AnthropicMessageSerializer } from '../anthropic/serializer.js';
|
|
24
|
-
import {
|
|
25
|
+
import { SchemaOptimizer, zodSchemaToJsonSchema } from '../schema.js';
|
|
25
26
|
export class ChatAnthropicBedrock {
|
|
26
27
|
model;
|
|
27
28
|
provider = 'anthropic_bedrock';
|
|
@@ -31,6 +32,8 @@ export class ChatAnthropicBedrock {
|
|
|
31
32
|
top_p;
|
|
32
33
|
top_k;
|
|
33
34
|
stop_sequences;
|
|
35
|
+
removeMinItemsFromSchema;
|
|
36
|
+
removeDefaultsFromSchema;
|
|
34
37
|
constructor(config = {}) {
|
|
35
38
|
// Anthropic Claude specific defaults
|
|
36
39
|
this.model = config.model || 'anthropic.claude-3-5-sonnet-20241022-v2:0';
|
|
@@ -41,8 +44,24 @@ export class ChatAnthropicBedrock {
|
|
|
41
44
|
this.top_k = config.top_k === undefined ? null : config.top_k;
|
|
42
45
|
this.stop_sequences =
|
|
43
46
|
config.stop_sequences === undefined ? null : config.stop_sequences;
|
|
47
|
+
this.removeMinItemsFromSchema = config.removeMinItemsFromSchema ?? false;
|
|
48
|
+
this.removeDefaultsFromSchema = config.removeDefaultsFromSchema ?? false;
|
|
44
49
|
const region = config.region || process.env.AWS_REGION || 'us-east-1';
|
|
45
|
-
|
|
50
|
+
const awsSessionToken = config.awsSessionToken || process.env.AWS_SESSION_TOKEN;
|
|
51
|
+
const credentials = config.awsAccessKeyId && config.awsSecretAccessKey
|
|
52
|
+
? {
|
|
53
|
+
accessKeyId: config.awsAccessKeyId,
|
|
54
|
+
secretAccessKey: config.awsSecretAccessKey,
|
|
55
|
+
...(awsSessionToken ? { sessionToken: awsSessionToken } : {}),
|
|
56
|
+
}
|
|
57
|
+
: undefined;
|
|
58
|
+
this.client = new BedrockRuntimeClient({
|
|
59
|
+
region,
|
|
60
|
+
...(credentials ? { credentials } : {}),
|
|
61
|
+
...(config.maxRetries !== undefined
|
|
62
|
+
? { maxAttempts: config.maxRetries }
|
|
63
|
+
: {}),
|
|
64
|
+
});
|
|
46
65
|
}
|
|
47
66
|
get name() {
|
|
48
67
|
return this.model;
|
|
@@ -65,6 +84,43 @@ export class ChatAnthropicBedrock {
|
|
|
65
84
|
}
|
|
66
85
|
return params;
|
|
67
86
|
}
|
|
87
|
+
getZodSchemaCandidate(output_format) {
|
|
88
|
+
const output = output_format;
|
|
89
|
+
if (output &&
|
|
90
|
+
typeof output === 'object' &&
|
|
91
|
+
typeof output.safeParse === 'function' &&
|
|
92
|
+
typeof output.parse === 'function') {
|
|
93
|
+
return output;
|
|
94
|
+
}
|
|
95
|
+
if (output &&
|
|
96
|
+
typeof output === 'object' &&
|
|
97
|
+
output.schema &&
|
|
98
|
+
typeof output.schema.safeParse === 'function' &&
|
|
99
|
+
typeof output.schema.parse === 'function') {
|
|
100
|
+
return output.schema;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
parseOutput(output_format, payload) {
|
|
105
|
+
const output = output_format;
|
|
106
|
+
if (output &&
|
|
107
|
+
typeof output === 'object' &&
|
|
108
|
+
output.schema &&
|
|
109
|
+
typeof output.schema.parse === 'function') {
|
|
110
|
+
return output.schema.parse(payload);
|
|
111
|
+
}
|
|
112
|
+
return output.parse(payload);
|
|
113
|
+
}
|
|
114
|
+
getTextCompletion(response) {
|
|
115
|
+
const contentBlocks = response?.output?.message?.content;
|
|
116
|
+
if (!Array.isArray(contentBlocks)) {
|
|
117
|
+
return '';
|
|
118
|
+
}
|
|
119
|
+
return contentBlocks
|
|
120
|
+
.filter((block) => typeof block?.text === 'string')
|
|
121
|
+
.map((block) => block.text)
|
|
122
|
+
.join('\n');
|
|
123
|
+
}
|
|
68
124
|
async ainvoke(messages, output_format, options = {}) {
|
|
69
125
|
// Use Anthropic-specific message serializer
|
|
70
126
|
const serializer = new AnthropicMessageSerializer();
|
|
@@ -76,8 +132,26 @@ export class ChatAnthropicBedrock {
|
|
|
76
132
|
if (block.type === 'text') {
|
|
77
133
|
return { text: block.text };
|
|
78
134
|
}
|
|
135
|
+
else if (block.type === 'tool_use') {
|
|
136
|
+
return {
|
|
137
|
+
toolUse: {
|
|
138
|
+
toolUseId: block.id,
|
|
139
|
+
name: block.name,
|
|
140
|
+
input: block.input,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
79
144
|
else if (block.type === 'image') {
|
|
80
|
-
|
|
145
|
+
if (block.source?.type === 'base64') {
|
|
146
|
+
return {
|
|
147
|
+
image: {
|
|
148
|
+
format: String(block.source.media_type || 'image/jpeg').split('/')[1] ?? 'jpeg',
|
|
149
|
+
source: {
|
|
150
|
+
bytes: Buffer.from(block.source.data ?? '', 'base64'),
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
81
155
|
return { text: '[Image]' };
|
|
82
156
|
}
|
|
83
157
|
return { text: String(block) };
|
|
@@ -98,15 +172,18 @@ export class ChatAnthropicBedrock {
|
|
|
98
172
|
},
|
|
99
173
|
]
|
|
100
174
|
: undefined;
|
|
101
|
-
let tools = undefined;
|
|
102
175
|
let toolConfig = undefined;
|
|
103
|
-
|
|
176
|
+
const zodSchemaCandidate = this.getZodSchemaCandidate(output_format);
|
|
177
|
+
if (output_format && zodSchemaCandidate) {
|
|
104
178
|
// Structured output using tools
|
|
105
179
|
try {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
:
|
|
109
|
-
|
|
180
|
+
const rawSchema = this._zodToJsonSchema(zodSchemaCandidate);
|
|
181
|
+
const schema = SchemaOptimizer.createOptimizedJsonSchema(rawSchema, {
|
|
182
|
+
removeMinItems: this.removeMinItemsFromSchema,
|
|
183
|
+
removeDefaults: this.removeDefaultsFromSchema,
|
|
184
|
+
});
|
|
185
|
+
delete schema.title;
|
|
186
|
+
const tools = [
|
|
110
187
|
{
|
|
111
188
|
toolSpec: {
|
|
112
189
|
name: 'extract_structured_data',
|
|
@@ -118,7 +195,7 @@ export class ChatAnthropicBedrock {
|
|
|
118
195
|
},
|
|
119
196
|
];
|
|
120
197
|
toolConfig = {
|
|
121
|
-
tools
|
|
198
|
+
tools,
|
|
122
199
|
toolChoice: { tool: { name: 'extract_structured_data' } },
|
|
123
200
|
};
|
|
124
201
|
}
|
|
@@ -133,31 +210,54 @@ export class ChatAnthropicBedrock {
|
|
|
133
210
|
toolConfig: toolConfig,
|
|
134
211
|
inferenceConfig: this._getInferenceParams(),
|
|
135
212
|
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const toolUseBlock =
|
|
141
|
-
|
|
142
|
-
|
|
213
|
+
try {
|
|
214
|
+
const response = await this.client.send(command, options.signal ? { abortSignal: options.signal } : undefined);
|
|
215
|
+
let completion = this.getTextCompletion(response);
|
|
216
|
+
const contentBlocks = response?.output?.message?.content;
|
|
217
|
+
const toolUseBlock = Array.isArray(contentBlocks)
|
|
218
|
+
? contentBlocks.find((block) => block?.toolUse)
|
|
219
|
+
: undefined;
|
|
220
|
+
if (toolUseBlock?.toolUse && output_format) {
|
|
221
|
+
const input = toolUseBlock.toolUse.input;
|
|
222
|
+
if (typeof input === 'string') {
|
|
223
|
+
completion = this.parseOutput(output_format, JSON.parse(input));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
completion = this.parseOutput(output_format, input);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else if (output_format && toolConfig) {
|
|
230
|
+
throw new ModelProviderError('Expected tool use in response but none found', 502, this.model);
|
|
231
|
+
}
|
|
232
|
+
else if (output_format) {
|
|
233
|
+
completion = this.parseOutput(output_format, completion);
|
|
143
234
|
}
|
|
144
235
|
else {
|
|
145
|
-
|
|
146
|
-
const textBlock = response.output.message.content.find((block) => block.text);
|
|
147
|
-
completion = textBlock?.text || '';
|
|
236
|
+
completion = this.getTextCompletion(response);
|
|
148
237
|
}
|
|
238
|
+
const stopReason = response?.stopReason ?? null;
|
|
239
|
+
return new ChatInvokeCompletion(completion, {
|
|
240
|
+
prompt_tokens: response.usage?.inputTokens ?? 0,
|
|
241
|
+
completion_tokens: response.usage?.outputTokens ?? 0,
|
|
242
|
+
total_tokens: response.usage?.totalTokens ?? 0,
|
|
243
|
+
}, null, null, stopReason);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const errorName = String(error?.name ?? '');
|
|
247
|
+
const statusCode = error?.$metadata?.httpStatusCode ?? 502;
|
|
248
|
+
if (statusCode === 429 ||
|
|
249
|
+
errorName.includes('Throttling') ||
|
|
250
|
+
errorName.includes('TooManyRequests')) {
|
|
251
|
+
throw new ModelRateLimitError(error?.message ?? 'Rate limit exceeded', 429, this.model);
|
|
252
|
+
}
|
|
253
|
+
throw new ModelProviderError(error?.message ?? String(error), statusCode, this.model);
|
|
149
254
|
}
|
|
150
|
-
return new ChatInvokeCompletion(completion, {
|
|
151
|
-
prompt_tokens: response.usage?.inputTokens ?? 0,
|
|
152
|
-
completion_tokens: response.usage?.outputTokens ?? 0,
|
|
153
|
-
total_tokens: response.usage?.totalTokens ?? 0,
|
|
154
|
-
});
|
|
155
255
|
}
|
|
156
256
|
/**
|
|
157
257
|
* Simple Zod to JSON Schema conversion for structured output
|
|
158
258
|
*/
|
|
159
259
|
_zodToJsonSchema(schema) {
|
|
160
|
-
return
|
|
260
|
+
return zodSchemaToJsonSchema(schema, {
|
|
161
261
|
name: 'Response',
|
|
162
262
|
target: 'jsonSchema7',
|
|
163
263
|
});
|
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
import type { BaseChatModel, ChatInvokeOptions } from '../base.js';
|
|
2
2
|
import { ChatInvokeCompletion } from '../views.js';
|
|
3
3
|
import { type Message } from '../messages.js';
|
|
4
|
+
export interface ChatBedrockConverseOptions {
|
|
5
|
+
model?: string;
|
|
6
|
+
region?: string;
|
|
7
|
+
awsAccessKeyId?: string;
|
|
8
|
+
awsSecretAccessKey?: string;
|
|
9
|
+
awsSessionToken?: string;
|
|
10
|
+
maxTokens?: number | null;
|
|
11
|
+
temperature?: number | null;
|
|
12
|
+
topP?: number | null;
|
|
13
|
+
seed?: number | null;
|
|
14
|
+
stopSequences?: string[] | null;
|
|
15
|
+
maxRetries?: number;
|
|
16
|
+
removeMinItemsFromSchema?: boolean;
|
|
17
|
+
removeDefaultsFromSchema?: boolean;
|
|
18
|
+
}
|
|
4
19
|
export declare class ChatBedrockConverse implements BaseChatModel {
|
|
5
20
|
model: string;
|
|
6
21
|
provider: string;
|
|
7
22
|
private client;
|
|
8
|
-
|
|
23
|
+
private maxTokens;
|
|
24
|
+
private temperature;
|
|
25
|
+
private topP;
|
|
26
|
+
private seed;
|
|
27
|
+
private stopSequences;
|
|
28
|
+
private removeMinItemsFromSchema;
|
|
29
|
+
private removeDefaultsFromSchema;
|
|
30
|
+
constructor(modelOrOptions?: string | ChatBedrockConverseOptions, region?: string);
|
|
9
31
|
get name(): string;
|
|
10
32
|
get model_name(): string;
|
|
33
|
+
private getInferenceConfig;
|
|
34
|
+
private getUsage;
|
|
35
|
+
private getZodSchemaCandidate;
|
|
36
|
+
private parseOutput;
|
|
37
|
+
private getTextCompletion;
|
|
11
38
|
ainvoke(messages: Message[], output_format?: undefined, options?: ChatInvokeOptions): Promise<ChatInvokeCompletion<string>>;
|
|
12
39
|
ainvoke<T>(messages: Message[], output_format: {
|
|
13
40
|
parse: (input: string) => T;
|
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
import { BedrockRuntimeClient, ConverseCommand, } from '@aws-sdk/client-bedrock-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { ModelProviderError, ModelRateLimitError } from '../exceptions.js';
|
|
3
3
|
import { ChatInvokeCompletion } from '../views.js';
|
|
4
|
-
import {
|
|
4
|
+
import { SchemaOptimizer, zodSchemaToJsonSchema } from '../schema.js';
|
|
5
5
|
import { AWSBedrockMessageSerializer } from './serializer.js';
|
|
6
6
|
export class ChatBedrockConverse {
|
|
7
7
|
model;
|
|
8
8
|
provider = 'aws';
|
|
9
9
|
client;
|
|
10
|
-
|
|
10
|
+
maxTokens;
|
|
11
|
+
temperature;
|
|
12
|
+
topP;
|
|
13
|
+
seed;
|
|
14
|
+
stopSequences;
|
|
15
|
+
removeMinItemsFromSchema;
|
|
16
|
+
removeDefaultsFromSchema;
|
|
17
|
+
constructor(modelOrOptions = {}, region) {
|
|
18
|
+
const normalizedOptions = typeof modelOrOptions === 'string'
|
|
19
|
+
? { model: modelOrOptions, region }
|
|
20
|
+
: modelOrOptions;
|
|
21
|
+
const { model = 'anthropic.claude-3-5-sonnet-20240620-v1:0', region: bedrockRegion = process.env.AWS_REGION || 'us-east-1', awsAccessKeyId, awsSecretAccessKey, awsSessionToken = process.env.AWS_SESSION_TOKEN, maxTokens = 4096, temperature = null, topP = null, seed = null, stopSequences = null, maxRetries, removeMinItemsFromSchema = false, removeDefaultsFromSchema = false, } = normalizedOptions;
|
|
11
22
|
this.model = model;
|
|
12
|
-
this.
|
|
23
|
+
this.maxTokens = maxTokens;
|
|
24
|
+
this.temperature = temperature;
|
|
25
|
+
this.topP = topP;
|
|
26
|
+
this.seed = seed;
|
|
27
|
+
this.stopSequences = stopSequences;
|
|
28
|
+
this.removeMinItemsFromSchema = removeMinItemsFromSchema;
|
|
29
|
+
this.removeDefaultsFromSchema = removeDefaultsFromSchema;
|
|
30
|
+
const credentials = awsAccessKeyId && awsSecretAccessKey
|
|
31
|
+
? {
|
|
32
|
+
accessKeyId: awsAccessKeyId,
|
|
33
|
+
secretAccessKey: awsSecretAccessKey,
|
|
34
|
+
...(awsSessionToken ? { sessionToken: awsSessionToken } : {}),
|
|
35
|
+
}
|
|
36
|
+
: undefined;
|
|
37
|
+
this.client = new BedrockRuntimeClient({
|
|
38
|
+
region: bedrockRegion,
|
|
39
|
+
...(credentials ? { credentials } : {}),
|
|
40
|
+
...(maxRetries !== undefined ? { maxAttempts: maxRetries } : {}),
|
|
41
|
+
});
|
|
13
42
|
}
|
|
14
43
|
get name() {
|
|
15
44
|
return this.model;
|
|
@@ -17,32 +46,102 @@ export class ChatBedrockConverse {
|
|
|
17
46
|
get model_name() {
|
|
18
47
|
return this.model;
|
|
19
48
|
}
|
|
49
|
+
getInferenceConfig() {
|
|
50
|
+
const config = {};
|
|
51
|
+
if (this.maxTokens !== null) {
|
|
52
|
+
config.maxTokens = this.maxTokens;
|
|
53
|
+
}
|
|
54
|
+
if (this.temperature !== null) {
|
|
55
|
+
config.temperature = this.temperature;
|
|
56
|
+
}
|
|
57
|
+
if (this.topP !== null) {
|
|
58
|
+
config.topP = this.topP;
|
|
59
|
+
}
|
|
60
|
+
if (this.seed !== null) {
|
|
61
|
+
config.seed = this.seed;
|
|
62
|
+
}
|
|
63
|
+
if (this.stopSequences !== null) {
|
|
64
|
+
config.stopSequences = this.stopSequences;
|
|
65
|
+
}
|
|
66
|
+
return config;
|
|
67
|
+
}
|
|
68
|
+
getUsage(response) {
|
|
69
|
+
const usage = response?.usage ?? {};
|
|
70
|
+
return {
|
|
71
|
+
prompt_tokens: usage.inputTokens ?? 0,
|
|
72
|
+
completion_tokens: usage.outputTokens ?? 0,
|
|
73
|
+
total_tokens: usage.totalTokens ?? 0,
|
|
74
|
+
prompt_cached_tokens: null,
|
|
75
|
+
prompt_cache_creation_tokens: null,
|
|
76
|
+
prompt_image_tokens: null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
getZodSchemaCandidate(output_format) {
|
|
80
|
+
const output = output_format;
|
|
81
|
+
if (output &&
|
|
82
|
+
typeof output === 'object' &&
|
|
83
|
+
typeof output.safeParse === 'function' &&
|
|
84
|
+
typeof output.parse === 'function') {
|
|
85
|
+
return output;
|
|
86
|
+
}
|
|
87
|
+
if (output &&
|
|
88
|
+
typeof output === 'object' &&
|
|
89
|
+
output.schema &&
|
|
90
|
+
typeof output.schema.safeParse === 'function' &&
|
|
91
|
+
typeof output.schema.parse === 'function') {
|
|
92
|
+
return output.schema;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
parseOutput(output_format, payload) {
|
|
97
|
+
const output = output_format;
|
|
98
|
+
if (output &&
|
|
99
|
+
typeof output === 'object' &&
|
|
100
|
+
output.schema &&
|
|
101
|
+
typeof output.schema.parse === 'function') {
|
|
102
|
+
return output.schema.parse(payload);
|
|
103
|
+
}
|
|
104
|
+
return output.parse(payload);
|
|
105
|
+
}
|
|
106
|
+
getTextCompletion(response) {
|
|
107
|
+
const contentBlocks = response?.output?.message?.content;
|
|
108
|
+
if (!Array.isArray(contentBlocks)) {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
return contentBlocks
|
|
112
|
+
.filter((block) => typeof block?.text === 'string')
|
|
113
|
+
.map((block) => block.text)
|
|
114
|
+
.join('\n');
|
|
115
|
+
}
|
|
20
116
|
async ainvoke(messages, output_format, options = {}) {
|
|
21
117
|
const serializer = new AWSBedrockMessageSerializer();
|
|
22
|
-
const bedrockMessages = serializer.
|
|
23
|
-
const
|
|
24
|
-
const system = systemMessage ? [{ text: systemMessage.text }] : undefined;
|
|
25
|
-
let tools = undefined;
|
|
118
|
+
const [bedrockMessages, systemMessage] = serializer.serializeMessages(messages);
|
|
119
|
+
const zodSchemaCandidate = this.getZodSchemaCandidate(output_format);
|
|
26
120
|
let toolConfig = undefined;
|
|
27
|
-
if (output_format &&
|
|
121
|
+
if (output_format && zodSchemaCandidate) {
|
|
28
122
|
try {
|
|
29
|
-
const
|
|
123
|
+
const rawJsonSchema = zodSchemaToJsonSchema(zodSchemaCandidate, {
|
|
30
124
|
name: 'Response',
|
|
31
125
|
target: 'jsonSchema7',
|
|
32
126
|
});
|
|
33
|
-
|
|
127
|
+
const optimizedJsonSchema = SchemaOptimizer.createOptimizedJsonSchema(rawJsonSchema, {
|
|
128
|
+
removeMinItems: this.removeMinItemsFromSchema,
|
|
129
|
+
removeDefaults: this.removeDefaultsFromSchema,
|
|
130
|
+
});
|
|
131
|
+
delete optimizedJsonSchema.title;
|
|
132
|
+
const tools = [
|
|
34
133
|
{
|
|
35
134
|
toolSpec: {
|
|
36
135
|
name: 'response',
|
|
37
|
-
description: '
|
|
136
|
+
description: 'Extract information in the format of response',
|
|
38
137
|
inputSchema: {
|
|
39
|
-
json:
|
|
138
|
+
json: optimizedJsonSchema,
|
|
40
139
|
},
|
|
41
140
|
},
|
|
42
141
|
},
|
|
43
142
|
];
|
|
44
143
|
toolConfig = {
|
|
45
|
-
tools
|
|
144
|
+
tools,
|
|
46
145
|
toolChoice: { tool: { name: 'response' } },
|
|
47
146
|
};
|
|
48
147
|
}
|
|
@@ -50,31 +149,59 @@ export class ChatBedrockConverse {
|
|
|
50
149
|
console.warn('Failed to convert output_format to JSON schema for AWS Bedrock', e);
|
|
51
150
|
}
|
|
52
151
|
}
|
|
53
|
-
const
|
|
152
|
+
const requestPayload = {
|
|
54
153
|
modelId: this.model,
|
|
55
154
|
messages: bedrockMessages,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
155
|
+
};
|
|
156
|
+
if (systemMessage) {
|
|
157
|
+
requestPayload.system = systemMessage;
|
|
158
|
+
}
|
|
159
|
+
const inferenceConfig = this.getInferenceConfig();
|
|
160
|
+
if (Object.keys(inferenceConfig).length) {
|
|
161
|
+
requestPayload.inferenceConfig = inferenceConfig;
|
|
162
|
+
}
|
|
163
|
+
if (toolConfig) {
|
|
164
|
+
requestPayload.toolConfig = toolConfig;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const response = await this.client.send(new ConverseCommand(requestPayload), options.signal ? { abortSignal: options.signal } : undefined);
|
|
168
|
+
let completion = this.getTextCompletion(response);
|
|
169
|
+
if (output_format) {
|
|
170
|
+
const contentBlocks = response?.output?.message?.content;
|
|
171
|
+
const toolUseBlock = Array.isArray(contentBlocks)
|
|
172
|
+
? contentBlocks.find((block) => block?.toolUse)
|
|
173
|
+
: undefined;
|
|
174
|
+
if (toolUseBlock?.toolUse) {
|
|
175
|
+
const input = toolUseBlock.toolUse.input;
|
|
176
|
+
if (typeof input === 'string') {
|
|
177
|
+
completion = this.parseOutput(output_format, JSON.parse(input));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
completion = this.parseOutput(output_format, input);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (toolConfig) {
|
|
184
|
+
throw new ModelProviderError('Expected tool use in response but none found', 502, this.model);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
completion = this.parseOutput(output_format, completion);
|
|
188
|
+
}
|
|
66
189
|
}
|
|
67
190
|
else {
|
|
68
|
-
|
|
69
|
-
const textBlock = response.output.message.content.find((block) => block.text);
|
|
70
|
-
completion = textBlock?.text || '';
|
|
191
|
+
completion = this.getTextCompletion(response);
|
|
71
192
|
}
|
|
193
|
+
const stopReason = response?.stopReason ?? null;
|
|
194
|
+
return new ChatInvokeCompletion(completion, this.getUsage(response), null, null, stopReason);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
const errorName = String(error?.name ?? '');
|
|
198
|
+
const statusCode = error?.$metadata?.httpStatusCode ?? 502;
|
|
199
|
+
if (statusCode === 429 ||
|
|
200
|
+
errorName.includes('Throttling') ||
|
|
201
|
+
errorName.includes('TooManyRequests')) {
|
|
202
|
+
throw new ModelRateLimitError(error?.message ?? 'Rate limit exceeded', 429, this.model);
|
|
203
|
+
}
|
|
204
|
+
throw new ModelProviderError(error?.message ?? String(error), statusCode, this.model);
|
|
72
205
|
}
|
|
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
206
|
}
|
|
80
207
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { type Message } from '../messages.js';
|
|
2
|
+
type BedrockContentBlock = Record<string, unknown>;
|
|
3
|
+
type BedrockMessage = {
|
|
4
|
+
role: 'user' | 'assistant';
|
|
5
|
+
content: BedrockContentBlock[];
|
|
6
|
+
};
|
|
7
|
+
type BedrockSystemMessage = {
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
2
10
|
export declare class AWSBedrockMessageSerializer {
|
|
3
|
-
serialize(messages: Message[]):
|
|
11
|
+
serialize(messages: Message[]): BedrockMessage[];
|
|
12
|
+
serializeMessages(messages: Message[]): [BedrockMessage[], BedrockSystemMessage?];
|
|
13
|
+
private serializeSystemContent;
|
|
14
|
+
private serializeImageContent;
|
|
4
15
|
private serializeMessage;
|
|
5
16
|
}
|
|
17
|
+
export {};
|
|
@@ -1,11 +1,44 @@
|
|
|
1
|
-
import { AssistantMessage, ContentPartImageParam, ContentPartTextParam, SystemMessage, UserMessage, } from '../messages.js';
|
|
2
|
-
// AWS Bedrock types are a bit complex and vary by model.
|
|
3
|
-
// We will define a generic structure that fits most Bedrock models (like Claude on Bedrock).
|
|
1
|
+
import { AssistantMessage, ContentPartImageParam, ContentPartRefusalParam, ContentPartTextParam, SystemMessage, UserMessage, } from '../messages.js';
|
|
4
2
|
export class AWSBedrockMessageSerializer {
|
|
5
3
|
serialize(messages) {
|
|
6
|
-
return messages
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
return this.serializeMessages(messages)[0];
|
|
5
|
+
}
|
|
6
|
+
serializeMessages(messages) {
|
|
7
|
+
const bedrockMessages = [];
|
|
8
|
+
let systemMessage = undefined;
|
|
9
|
+
for (const message of messages) {
|
|
10
|
+
if (message instanceof SystemMessage) {
|
|
11
|
+
systemMessage = this.serializeSystemContent(message.content);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
bedrockMessages.push(this.serializeMessage(message));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return [bedrockMessages, systemMessage];
|
|
18
|
+
}
|
|
19
|
+
serializeSystemContent(content) {
|
|
20
|
+
if (typeof content === 'string') {
|
|
21
|
+
return [{ text: content }];
|
|
22
|
+
}
|
|
23
|
+
return content
|
|
24
|
+
.filter((part) => part instanceof ContentPartTextParam)
|
|
25
|
+
.map((part) => ({ text: part.text }));
|
|
26
|
+
}
|
|
27
|
+
serializeImageContent(part) {
|
|
28
|
+
const url = part.image_url.url;
|
|
29
|
+
if (!url.startsWith('data:')) {
|
|
30
|
+
throw new Error(`Unsupported image URL format: ${url}`);
|
|
31
|
+
}
|
|
32
|
+
const [, payload = ''] = url.split(',', 2);
|
|
33
|
+
const format = part.image_url.media_type.split('/')[1] ?? 'jpeg';
|
|
34
|
+
return {
|
|
35
|
+
image: {
|
|
36
|
+
format,
|
|
37
|
+
source: {
|
|
38
|
+
bytes: Buffer.from(payload, 'base64'),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
9
42
|
}
|
|
10
43
|
serializeMessage(message) {
|
|
11
44
|
if (message instanceof UserMessage) {
|
|
@@ -17,16 +50,7 @@ export class AWSBedrockMessageSerializer {
|
|
|
17
50
|
return { text: part.text };
|
|
18
51
|
}
|
|
19
52
|
if (part instanceof ContentPartImageParam) {
|
|
20
|
-
|
|
21
|
-
const data = part.image_url.url.split(',')[1];
|
|
22
|
-
return {
|
|
23
|
-
image: {
|
|
24
|
-
format: mediaType.split('/')[1], // e.g. 'png' from 'image/png'
|
|
25
|
-
source: {
|
|
26
|
-
bytes: Buffer.from(data, 'base64'),
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
};
|
|
53
|
+
return this.serializeImageContent(part);
|
|
30
54
|
}
|
|
31
55
|
return { text: '' };
|
|
32
56
|
})
|
|
@@ -44,20 +68,35 @@ export class AWSBedrockMessageSerializer {
|
|
|
44
68
|
if (part instanceof ContentPartTextParam) {
|
|
45
69
|
content.push({ text: part.text });
|
|
46
70
|
}
|
|
71
|
+
else if (part instanceof ContentPartRefusalParam) {
|
|
72
|
+
content.push({ text: `[Refusal] ${part.refusal}` });
|
|
73
|
+
}
|
|
47
74
|
});
|
|
48
75
|
}
|
|
49
76
|
}
|
|
50
77
|
if (message.tool_calls) {
|
|
51
78
|
message.tool_calls.forEach((toolCall) => {
|
|
79
|
+
let parsedArguments;
|
|
80
|
+
try {
|
|
81
|
+
parsedArguments = JSON.parse(toolCall.functionCall.arguments);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
parsedArguments = {
|
|
85
|
+
arguments: toolCall.functionCall.arguments,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
52
88
|
content.push({
|
|
53
89
|
toolUse: {
|
|
54
90
|
toolUseId: toolCall.id,
|
|
55
91
|
name: toolCall.functionCall.name,
|
|
56
|
-
input:
|
|
92
|
+
input: parsedArguments,
|
|
57
93
|
},
|
|
58
94
|
});
|
|
59
95
|
});
|
|
60
96
|
}
|
|
97
|
+
if (!content.length) {
|
|
98
|
+
content.push({ text: '' });
|
|
99
|
+
}
|
|
61
100
|
return {
|
|
62
101
|
role: 'assistant',
|
|
63
102
|
content: content,
|