@librechat/agents 3.1.75 → 3.1.77-dev.1
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/dist/cjs/graphs/Graph.cjs +22 -3
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/hitl/askUserQuestion.cjs +67 -0
- package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -0
- package/dist/cjs/hooks/HookRegistry.cjs +54 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/createToolPolicyHook.cjs +115 -0
- package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -0
- package/dist/cjs/hooks/executeHooks.cjs +40 -1
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +1 -0
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/langchain/google-common.cjs +3 -0
- package/dist/cjs/langchain/google-common.cjs.map +1 -0
- package/dist/cjs/langchain/index.cjs +86 -0
- package/dist/cjs/langchain/index.cjs.map +1 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs +3 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs.map +1 -0
- package/dist/cjs/langchain/messages/tool.cjs +3 -0
- package/dist/cjs/langchain/messages/tool.cjs.map +1 -0
- package/dist/cjs/langchain/messages.cjs +51 -0
- package/dist/cjs/langchain/messages.cjs.map +1 -0
- package/dist/cjs/langchain/openai.cjs +3 -0
- package/dist/cjs/langchain/openai.cjs.map +1 -0
- package/dist/cjs/langchain/prompts.cjs +11 -0
- package/dist/cjs/langchain/prompts.cjs.map +1 -0
- package/dist/cjs/langchain/runnables.cjs +19 -0
- package/dist/cjs/langchain/runnables.cjs.map +1 -0
- package/dist/cjs/langchain/tools.cjs +23 -0
- package/dist/cjs/langchain/tools.cjs.map +1 -0
- package/dist/cjs/langchain/utils/env.cjs +11 -0
- package/dist/cjs/langchain/utils/env.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +145 -52
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +21 -14
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +84 -70
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +1 -1
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +213 -3
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +2 -1
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +5 -4
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +519 -655
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +20 -458
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +57 -175
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +5 -3
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +112 -3
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +2 -1
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +7 -6
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +73 -15
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/langchain.cjs +26 -0
- package/dist/cjs/messages/langchain.cjs.map +1 -0
- package/dist/cjs/messages/prune.cjs +7 -6
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +400 -42
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +556 -56
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +55 -66
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tavily-search.cjs +372 -0
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +26 -4
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +10 -3
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +22 -3
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/hitl/askUserQuestion.mjs +65 -0
- package/dist/esm/hitl/askUserQuestion.mjs.map +1 -0
- package/dist/esm/hooks/HookRegistry.mjs +54 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/createToolPolicyHook.mjs +113 -0
- package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -0
- package/dist/esm/hooks/executeHooks.mjs +40 -1
- package/dist/esm/hooks/executeHooks.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +1 -0
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/langchain/google-common.mjs +2 -0
- package/dist/esm/langchain/google-common.mjs.map +1 -0
- package/dist/esm/langchain/index.mjs +5 -0
- package/dist/esm/langchain/index.mjs.map +1 -0
- package/dist/esm/langchain/language_models/chat_models.mjs +2 -0
- package/dist/esm/langchain/language_models/chat_models.mjs.map +1 -0
- package/dist/esm/langchain/messages/tool.mjs +2 -0
- package/dist/esm/langchain/messages/tool.mjs.map +1 -0
- package/dist/esm/langchain/messages.mjs +2 -0
- package/dist/esm/langchain/messages.mjs.map +1 -0
- package/dist/esm/langchain/openai.mjs +2 -0
- package/dist/esm/langchain/openai.mjs.map +1 -0
- package/dist/esm/langchain/prompts.mjs +2 -0
- package/dist/esm/langchain/prompts.mjs.map +1 -0
- package/dist/esm/langchain/runnables.mjs +2 -0
- package/dist/esm/langchain/runnables.mjs.map +1 -0
- package/dist/esm/langchain/tools.mjs +2 -0
- package/dist/esm/langchain/tools.mjs.map +1 -0
- package/dist/esm/langchain/utils/env.mjs +2 -0
- package/dist/esm/langchain/utils/env.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +146 -54
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +21 -14
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +84 -71
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +1 -1
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +214 -4
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs +2 -1
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +5 -4
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +520 -656
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +23 -459
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +57 -175
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +5 -3
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +7 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +2 -1
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +7 -6
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +73 -15
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/langchain.mjs +23 -0
- package/dist/esm/messages/langchain.mjs.map +1 -0
- package/dist/esm/messages/prune.mjs +7 -6
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +400 -42
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +557 -57
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +55 -66
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
- package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tavily-search.mjs +370 -0
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +26 -4
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +10 -3
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +7 -0
- package/dist/types/hitl/askUserQuestion.d.ts +55 -0
- package/dist/types/hitl/index.d.ts +6 -0
- package/dist/types/hooks/HookRegistry.d.ts +58 -0
- package/dist/types/hooks/createToolPolicyHook.d.ts +87 -0
- package/dist/types/hooks/index.d.ts +4 -1
- package/dist/types/hooks/types.d.ts +109 -3
- package/dist/types/index.d.ts +10 -0
- package/dist/types/langchain/google-common.d.ts +1 -0
- package/dist/types/langchain/index.d.ts +8 -0
- package/dist/types/langchain/language_models/chat_models.d.ts +1 -0
- package/dist/types/langchain/messages/tool.d.ts +1 -0
- package/dist/types/langchain/messages.d.ts +2 -0
- package/dist/types/langchain/openai.d.ts +1 -0
- package/dist/types/langchain/prompts.d.ts +1 -0
- package/dist/types/langchain/runnables.d.ts +2 -0
- package/dist/types/langchain/tools.d.ts +2 -0
- package/dist/types/langchain/utils/env.d.ts +1 -0
- package/dist/types/llm/anthropic/index.d.ts +22 -9
- package/dist/types/llm/anthropic/types.d.ts +5 -1
- package/dist/types/llm/anthropic/utils/message_outputs.d.ts +13 -6
- package/dist/types/llm/anthropic/utils/output_parsers.d.ts +1 -1
- package/dist/types/llm/openai/index.d.ts +21 -24
- package/dist/types/llm/openrouter/index.d.ts +11 -9
- package/dist/types/llm/vertexai/index.d.ts +1 -0
- package/dist/types/messages/cache.d.ts +4 -1
- package/dist/types/messages/format.d.ts +4 -1
- package/dist/types/messages/langchain.d.ts +27 -0
- package/dist/types/run.d.ts +117 -1
- package/dist/types/tools/ToolNode.d.ts +26 -1
- package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
- package/dist/types/tools/search/tavily-search.d.ts +4 -0
- package/dist/types/tools/search/types.d.ts +99 -5
- package/dist/types/tools/search/utils.d.ts +2 -2
- package/dist/types/types/graph.d.ts +23 -37
- package/dist/types/types/hitl.d.ts +272 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/llm.d.ts +3 -3
- package/dist/types/types/run.d.ts +33 -0
- package/dist/types/types/stream.d.ts +1 -1
- package/dist/types/types/tools.d.ts +19 -0
- package/package.json +80 -17
- package/src/graphs/Graph.ts +33 -4
- package/src/graphs/__tests__/composition.smoke.test.ts +188 -0
- package/src/hitl/askUserQuestion.ts +72 -0
- package/src/hitl/index.ts +7 -0
- package/src/hooks/HookRegistry.ts +71 -0
- package/src/hooks/__tests__/createToolPolicyHook.test.ts +259 -0
- package/src/hooks/createToolPolicyHook.ts +184 -0
- package/src/hooks/executeHooks.ts +50 -1
- package/src/hooks/index.ts +6 -0
- package/src/hooks/types.ts +112 -0
- package/src/index.ts +22 -0
- package/src/langchain/google-common.ts +1 -0
- package/src/langchain/index.ts +8 -0
- package/src/langchain/language_models/chat_models.ts +1 -0
- package/src/langchain/messages/tool.ts +5 -0
- package/src/langchain/messages.ts +21 -0
- package/src/langchain/openai.ts +1 -0
- package/src/langchain/prompts.ts +1 -0
- package/src/langchain/runnables.ts +7 -0
- package/src/langchain/tools.ts +8 -0
- package/src/langchain/utils/env.ts +1 -0
- package/src/llm/anthropic/index.ts +252 -84
- package/src/llm/anthropic/llm.spec.ts +751 -102
- package/src/llm/anthropic/types.ts +9 -1
- package/src/llm/anthropic/utils/message_inputs.ts +37 -19
- package/src/llm/anthropic/utils/message_outputs.ts +119 -101
- package/src/llm/bedrock/index.ts +2 -2
- package/src/llm/bedrock/llm.spec.ts +341 -0
- package/src/llm/bedrock/utils/message_inputs.ts +303 -4
- package/src/llm/bedrock/utils/message_outputs.ts +2 -1
- package/src/llm/custom-chat-models.smoke.test.ts +836 -0
- package/src/llm/google/llm.spec.ts +339 -57
- package/src/llm/google/utils/common.ts +53 -48
- package/src/llm/openai/contentBlocks.test.ts +346 -0
- package/src/llm/openai/index.ts +856 -833
- package/src/llm/openai/utils/index.ts +107 -78
- package/src/llm/openai/utils/messages.test.ts +159 -0
- package/src/llm/openrouter/index.ts +124 -247
- package/src/llm/openrouter/reasoning.test.ts +8 -1
- package/src/llm/vertexai/index.ts +11 -5
- package/src/llm/vertexai/llm.spec.ts +28 -1
- package/src/messages/cache.test.ts +4 -3
- package/src/messages/cache.ts +3 -2
- package/src/messages/core.ts +16 -9
- package/src/messages/format.ts +96 -16
- package/src/messages/formatAgentMessages.test.ts +166 -1
- package/src/messages/langchain.ts +39 -0
- package/src/messages/prune.ts +12 -8
- package/src/run.ts +456 -47
- package/src/scripts/caching.ts +2 -3
- package/src/specs/summarization.test.ts +51 -58
- package/src/tools/ToolNode.ts +706 -63
- package/src/tools/__tests__/hitl.test.ts +3593 -0
- package/src/tools/search/search.ts +83 -73
- package/src/tools/search/tavily-scraper.ts +235 -0
- package/src/tools/search/tavily-search.ts +424 -0
- package/src/tools/search/tavily.test.ts +965 -0
- package/src/tools/search/tool.ts +36 -26
- package/src/tools/search/types.ts +133 -8
- package/src/tools/search/utils.ts +13 -5
- package/src/types/graph.ts +32 -87
- package/src/types/hitl.ts +303 -0
- package/src/types/index.ts +1 -0
- package/src/types/llm.ts +3 -3
- package/src/types/run.ts +33 -0
- package/src/types/stream.ts +1 -1
- package/src/types/tools.ts +19 -0
- package/src/utils/llmConfig.ts +1 -6
|
@@ -9,12 +9,14 @@ import {
|
|
|
9
9
|
HumanMessage,
|
|
10
10
|
SystemMessage,
|
|
11
11
|
AIMessageChunk,
|
|
12
|
+
type MessageContentComplex,
|
|
12
13
|
} from '@langchain/core/messages';
|
|
13
14
|
import { concat } from '@langchain/core/utils/stream';
|
|
14
15
|
import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
15
16
|
import {
|
|
16
17
|
BedrockRuntimeClient,
|
|
17
18
|
ConverseCommand,
|
|
19
|
+
ConverseStreamCommand,
|
|
18
20
|
} from '@aws-sdk/client-bedrock-runtime';
|
|
19
21
|
import type { ConverseResponse } from '@aws-sdk/client-bedrock-runtime';
|
|
20
22
|
import {
|
|
@@ -22,6 +24,7 @@ import {
|
|
|
22
24
|
handleConverseStreamMetadata,
|
|
23
25
|
convertToConverseMessages,
|
|
24
26
|
} from './utils';
|
|
27
|
+
import { toLangChainContent } from '@/messages/langchain';
|
|
25
28
|
import { CustomChatBedrockConverse, ServiceTierType } from './index';
|
|
26
29
|
|
|
27
30
|
jest.setTimeout(120000);
|
|
@@ -35,6 +38,53 @@ const baseConstructorArgs = {
|
|
|
35
38
|
},
|
|
36
39
|
};
|
|
37
40
|
|
|
41
|
+
type ConverseContentBlock = NonNullable<
|
|
42
|
+
ReturnType<
|
|
43
|
+
typeof convertToConverseMessages
|
|
44
|
+
>['converseMessages'][number]['content']
|
|
45
|
+
>[number];
|
|
46
|
+
type BedrockVideoBlock = ConverseContentBlock & {
|
|
47
|
+
video: {
|
|
48
|
+
format?: string;
|
|
49
|
+
source?: { bytes?: Uint8Array; s3Location?: { uri?: string } };
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
type BedrockAudioBlock = ConverseContentBlock & {
|
|
53
|
+
audio: {
|
|
54
|
+
format?: string;
|
|
55
|
+
source?: { bytes?: Uint8Array; s3Location?: { uri?: string } };
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
type BedrockDocumentBlock = ConverseContentBlock & {
|
|
59
|
+
document: {
|
|
60
|
+
format?: string;
|
|
61
|
+
name?: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function expectVideoBlock(block: ConverseContentBlock): BedrockVideoBlock {
|
|
66
|
+
expect(block).toHaveProperty('video');
|
|
67
|
+
return block as BedrockVideoBlock;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function expectAudioBlock(block: ConverseContentBlock): BedrockAudioBlock {
|
|
71
|
+
expect(block).toHaveProperty('audio');
|
|
72
|
+
return block as BedrockAudioBlock;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function expectDocumentBlock(
|
|
76
|
+
block: ConverseContentBlock
|
|
77
|
+
): BedrockDocumentBlock {
|
|
78
|
+
expect(block).toHaveProperty('document');
|
|
79
|
+
return block as BedrockDocumentBlock;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function humanMessageWithContent(
|
|
83
|
+
content: MessageContentComplex[]
|
|
84
|
+
): HumanMessage {
|
|
85
|
+
return new HumanMessage({ content: toLangChainContent(content) });
|
|
86
|
+
}
|
|
87
|
+
|
|
38
88
|
describe('CustomChatBedrockConverse', () => {
|
|
39
89
|
describe('applicationInferenceProfile parameter', () => {
|
|
40
90
|
test('should initialize applicationInferenceProfile from constructor', () => {
|
|
@@ -135,6 +185,59 @@ describe('CustomChatBedrockConverse', () => {
|
|
|
135
185
|
'anthropic.claude-3-haiku-20240307-v1:0'
|
|
136
186
|
);
|
|
137
187
|
});
|
|
188
|
+
|
|
189
|
+
test('should send applicationInferenceProfile as modelId in ConverseStreamCommand when provided', async () => {
|
|
190
|
+
const testArn =
|
|
191
|
+
'arn:aws:bedrock:eu-west-1:123456789012:application-inference-profile/test-profile';
|
|
192
|
+
const mockSend = jest
|
|
193
|
+
.fn<
|
|
194
|
+
(command: ConverseStreamCommand) => Promise<{
|
|
195
|
+
stream: AsyncIterable<{
|
|
196
|
+
contentBlockDelta: {
|
|
197
|
+
contentBlockIndex: number;
|
|
198
|
+
delta: { text: string };
|
|
199
|
+
};
|
|
200
|
+
}>;
|
|
201
|
+
}>
|
|
202
|
+
>()
|
|
203
|
+
.mockResolvedValue({
|
|
204
|
+
stream: (async function* streamChunks() {
|
|
205
|
+
yield {
|
|
206
|
+
contentBlockDelta: {
|
|
207
|
+
contentBlockIndex: 0,
|
|
208
|
+
delta: { text: 'Test response' },
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
})(),
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const mockClient = {
|
|
215
|
+
send: mockSend,
|
|
216
|
+
} as unknown as BedrockRuntimeClient;
|
|
217
|
+
|
|
218
|
+
const model = new CustomChatBedrockConverse({
|
|
219
|
+
...baseConstructorArgs,
|
|
220
|
+
model: 'anthropic.claude-3-haiku-20240307-v1:0',
|
|
221
|
+
applicationInferenceProfile: testArn,
|
|
222
|
+
client: mockClient,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
let chunks = 0;
|
|
226
|
+
for await (const _chunk of await model.stream([
|
|
227
|
+
new HumanMessage('Hello'),
|
|
228
|
+
])) {
|
|
229
|
+
chunks += 1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
expect(mockSend).toHaveBeenCalledTimes(1);
|
|
233
|
+
expect(chunks).toBe(1);
|
|
234
|
+
const commandArg = mockSend.mock.calls[0][0] as ConverseStreamCommand;
|
|
235
|
+
expect(commandArg).toBeInstanceOf(ConverseStreamCommand);
|
|
236
|
+
expect(commandArg.input.modelId).toBe(testArn);
|
|
237
|
+
expect(commandArg.input.modelId).not.toBe(
|
|
238
|
+
'anthropic.claude-3-haiku-20240307-v1:0'
|
|
239
|
+
);
|
|
240
|
+
});
|
|
138
241
|
});
|
|
139
242
|
|
|
140
243
|
describe('serviceTier configuration', () => {
|
|
@@ -753,6 +856,244 @@ describe('convertToConverseMessages', () => {
|
|
|
753
856
|
'call_2'
|
|
754
857
|
);
|
|
755
858
|
});
|
|
859
|
+
|
|
860
|
+
describe('video content block conversion', () => {
|
|
861
|
+
test('converts multimodal video block with base64 data', () => {
|
|
862
|
+
const videoData = btoa('fake-video-bytes');
|
|
863
|
+
const result = convertToConverseMessages([
|
|
864
|
+
humanMessageWithContent([
|
|
865
|
+
{ type: 'text', text: 'Describe this video' },
|
|
866
|
+
{
|
|
867
|
+
type: 'video',
|
|
868
|
+
mimeType: 'video/mp4',
|
|
869
|
+
data: videoData,
|
|
870
|
+
} as MessageContentComplex,
|
|
871
|
+
]),
|
|
872
|
+
]);
|
|
873
|
+
|
|
874
|
+
const content = result.converseMessages[0].content!;
|
|
875
|
+
expect(content).toHaveLength(2);
|
|
876
|
+
expect(content[0]).toEqual({ text: 'Describe this video' });
|
|
877
|
+
const videoBlock = expectVideoBlock(content[1]);
|
|
878
|
+
expect(videoBlock.video.format).toBe('mp4');
|
|
879
|
+
expect(videoBlock.video.source?.bytes).toBeInstanceOf(Uint8Array);
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
test('converts multimodal video block with Uint8Array data', () => {
|
|
883
|
+
const videoBytes = new Uint8Array([1, 2, 3, 4]);
|
|
884
|
+
const result = convertToConverseMessages([
|
|
885
|
+
humanMessageWithContent([
|
|
886
|
+
{
|
|
887
|
+
type: 'video',
|
|
888
|
+
mimeType: 'video/webm',
|
|
889
|
+
data: videoBytes,
|
|
890
|
+
} as MessageContentComplex,
|
|
891
|
+
]),
|
|
892
|
+
]);
|
|
893
|
+
|
|
894
|
+
const content = result.converseMessages[0].content!;
|
|
895
|
+
const videoBlock = expectVideoBlock(content[0]);
|
|
896
|
+
expect(videoBlock.video.format).toBe('webm');
|
|
897
|
+
expect(videoBlock.video.source?.bytes).toBe(videoBytes);
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
test('passes through native Bedrock video block', () => {
|
|
901
|
+
const videoSource = {
|
|
902
|
+
bytes: new Uint8Array([1, 2, 3]),
|
|
903
|
+
};
|
|
904
|
+
const result = convertToConverseMessages([
|
|
905
|
+
humanMessageWithContent([
|
|
906
|
+
{
|
|
907
|
+
type: 'video',
|
|
908
|
+
video: {
|
|
909
|
+
format: 'mp4',
|
|
910
|
+
source: videoSource,
|
|
911
|
+
},
|
|
912
|
+
} as MessageContentComplex,
|
|
913
|
+
]),
|
|
914
|
+
]);
|
|
915
|
+
|
|
916
|
+
const content = result.converseMessages[0].content!;
|
|
917
|
+
const videoBlock = expectVideoBlock(content[0]);
|
|
918
|
+
expect(videoBlock.video.format).toBe('mp4');
|
|
919
|
+
expect(videoBlock.video.source).toBe(videoSource);
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
test('converts video block with S3 fileId', () => {
|
|
923
|
+
const result = convertToConverseMessages([
|
|
924
|
+
humanMessageWithContent([
|
|
925
|
+
{
|
|
926
|
+
type: 'video',
|
|
927
|
+
mimeType: 'video/mp4',
|
|
928
|
+
fileId: 's3://my-bucket/my-video.mp4',
|
|
929
|
+
} as MessageContentComplex,
|
|
930
|
+
]),
|
|
931
|
+
]);
|
|
932
|
+
|
|
933
|
+
const content = result.converseMessages[0].content!;
|
|
934
|
+
const videoBlock = expectVideoBlock(content[0]);
|
|
935
|
+
expect(videoBlock.video.format).toBe('mp4');
|
|
936
|
+
expect(videoBlock.video.source?.s3Location?.uri).toBe(
|
|
937
|
+
's3://my-bucket/my-video.mp4'
|
|
938
|
+
);
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
describe('audio content block conversion', () => {
|
|
943
|
+
test('converts multimodal audio block with base64 data', () => {
|
|
944
|
+
const audioData = btoa('fake-audio-bytes');
|
|
945
|
+
const result = convertToConverseMessages([
|
|
946
|
+
humanMessageWithContent([
|
|
947
|
+
{ type: 'text', text: 'Transcribe this audio' },
|
|
948
|
+
{
|
|
949
|
+
type: 'audio',
|
|
950
|
+
mimeType: 'audio/mp3',
|
|
951
|
+
data: audioData,
|
|
952
|
+
} as MessageContentComplex,
|
|
953
|
+
]),
|
|
954
|
+
]);
|
|
955
|
+
|
|
956
|
+
const content = result.converseMessages[0].content!;
|
|
957
|
+
expect(content).toHaveLength(2);
|
|
958
|
+
expect(content[0]).toEqual({ text: 'Transcribe this audio' });
|
|
959
|
+
const audioBlock = expectAudioBlock(content[1]);
|
|
960
|
+
expect(audioBlock.audio.format).toBe('mp3');
|
|
961
|
+
expect(audioBlock.audio.source?.bytes).toBeInstanceOf(Uint8Array);
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
test('converts multimodal audio block with Uint8Array data', () => {
|
|
965
|
+
const audioBytes = new Uint8Array([1, 2, 3, 4]);
|
|
966
|
+
const result = convertToConverseMessages([
|
|
967
|
+
humanMessageWithContent([
|
|
968
|
+
{
|
|
969
|
+
type: 'audio',
|
|
970
|
+
mimeType: 'audio/wav',
|
|
971
|
+
data: audioBytes,
|
|
972
|
+
} as MessageContentComplex,
|
|
973
|
+
]),
|
|
974
|
+
]);
|
|
975
|
+
|
|
976
|
+
const content = result.converseMessages[0].content!;
|
|
977
|
+
const audioBlock = expectAudioBlock(content[0]);
|
|
978
|
+
expect(audioBlock.audio.format).toBe('wav');
|
|
979
|
+
expect(audioBlock.audio.source?.bytes).toBe(audioBytes);
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
test('passes through native Bedrock audio block', () => {
|
|
983
|
+
const audioSource = {
|
|
984
|
+
bytes: new Uint8Array([1, 2, 3]),
|
|
985
|
+
};
|
|
986
|
+
const result = convertToConverseMessages([
|
|
987
|
+
humanMessageWithContent([
|
|
988
|
+
{
|
|
989
|
+
type: 'audio',
|
|
990
|
+
audio: {
|
|
991
|
+
format: 'flac',
|
|
992
|
+
source: audioSource,
|
|
993
|
+
},
|
|
994
|
+
} as MessageContentComplex,
|
|
995
|
+
]),
|
|
996
|
+
]);
|
|
997
|
+
|
|
998
|
+
const content = result.converseMessages[0].content!;
|
|
999
|
+
const audioBlock = expectAudioBlock(content[0]);
|
|
1000
|
+
expect(audioBlock.audio.format).toBe('flac');
|
|
1001
|
+
expect(audioBlock.audio.source).toBe(audioSource);
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
test('converts audio block with S3 fileId', () => {
|
|
1005
|
+
const result = convertToConverseMessages([
|
|
1006
|
+
humanMessageWithContent([
|
|
1007
|
+
{
|
|
1008
|
+
type: 'audio',
|
|
1009
|
+
mimeType: 'audio/mp3',
|
|
1010
|
+
fileId: 's3://my-bucket/my-audio.mp3',
|
|
1011
|
+
} as MessageContentComplex,
|
|
1012
|
+
]),
|
|
1013
|
+
]);
|
|
1014
|
+
|
|
1015
|
+
const content = result.converseMessages[0].content!;
|
|
1016
|
+
const audioBlock = expectAudioBlock(content[0]);
|
|
1017
|
+
expect(audioBlock.audio.format).toBe('mp3');
|
|
1018
|
+
expect(audioBlock.audio.source?.s3Location?.uri).toBe(
|
|
1019
|
+
's3://my-bucket/my-audio.mp3'
|
|
1020
|
+
);
|
|
1021
|
+
});
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
describe('document content block conversion', () => {
|
|
1025
|
+
test('imputes placeholder filename when no name is provided', () => {
|
|
1026
|
+
const pdfData = btoa('fake-pdf-bytes');
|
|
1027
|
+
const result = convertToConverseMessages([
|
|
1028
|
+
humanMessageWithContent([
|
|
1029
|
+
{
|
|
1030
|
+
type: 'file',
|
|
1031
|
+
source_type: 'base64',
|
|
1032
|
+
mime_type: 'application/pdf',
|
|
1033
|
+
data: pdfData,
|
|
1034
|
+
} as MessageContentComplex,
|
|
1035
|
+
]),
|
|
1036
|
+
]);
|
|
1037
|
+
|
|
1038
|
+
const content = result.converseMessages[0].content!;
|
|
1039
|
+
expect(content).toHaveLength(1);
|
|
1040
|
+
const documentBlock = expectDocumentBlock(content[0]);
|
|
1041
|
+
expect(documentBlock.document.format).toBe('pdf');
|
|
1042
|
+
expect(documentBlock.document.name).toBeDefined();
|
|
1043
|
+
expect(typeof documentBlock.document.name).toBe('string');
|
|
1044
|
+
expect(documentBlock.document.name?.length).toBe(12);
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
test('uses provided filename from metadata', () => {
|
|
1048
|
+
const pdfData = btoa('fake-pdf-bytes');
|
|
1049
|
+
const result = convertToConverseMessages([
|
|
1050
|
+
humanMessageWithContent([
|
|
1051
|
+
{
|
|
1052
|
+
type: 'file',
|
|
1053
|
+
source_type: 'base64',
|
|
1054
|
+
mime_type: 'application/pdf',
|
|
1055
|
+
data: pdfData,
|
|
1056
|
+
metadata: { filename: 'my-report.pdf' },
|
|
1057
|
+
} as MessageContentComplex,
|
|
1058
|
+
]),
|
|
1059
|
+
]);
|
|
1060
|
+
|
|
1061
|
+
const content = result.converseMessages[0].content!;
|
|
1062
|
+
expect(expectDocumentBlock(content[0]).document.name).toBe(
|
|
1063
|
+
'my-report.pdf'
|
|
1064
|
+
);
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
test('generates unique placeholder filenames for multiple files', () => {
|
|
1068
|
+
const pdfData = btoa('fake-pdf-bytes');
|
|
1069
|
+
const result = convertToConverseMessages([
|
|
1070
|
+
humanMessageWithContent([
|
|
1071
|
+
{
|
|
1072
|
+
type: 'file',
|
|
1073
|
+
source_type: 'base64',
|
|
1074
|
+
mime_type: 'application/pdf',
|
|
1075
|
+
data: pdfData,
|
|
1076
|
+
} as MessageContentComplex,
|
|
1077
|
+
{
|
|
1078
|
+
type: 'file',
|
|
1079
|
+
source_type: 'base64',
|
|
1080
|
+
mime_type: 'application/pdf',
|
|
1081
|
+
data: pdfData,
|
|
1082
|
+
} as MessageContentComplex,
|
|
1083
|
+
]),
|
|
1084
|
+
]);
|
|
1085
|
+
|
|
1086
|
+
const content = result.converseMessages[0].content!;
|
|
1087
|
+
expect(content).toHaveLength(2);
|
|
1088
|
+
const firstDocument = expectDocumentBlock(content[0]);
|
|
1089
|
+
const secondDocument = expectDocumentBlock(content[1]);
|
|
1090
|
+
expect(firstDocument.document.name).toBeDefined();
|
|
1091
|
+
expect(secondDocument.document.name).toBeDefined();
|
|
1092
|
+
expect(firstDocument.document.name).not.toBe(
|
|
1093
|
+
secondDocument.document.name
|
|
1094
|
+
);
|
|
1095
|
+
});
|
|
1096
|
+
});
|
|
756
1097
|
});
|
|
757
1098
|
|
|
758
1099
|
// Integration tests (require AWS credentials)
|