Skip to content

Commit a96e2b9

Browse files
author
wmz7year
committed
Re-implementing Amazon Bedrock Chat model with Amazon Bedrock Converse API.
1 parent e4ee01a commit a96e2b9

File tree

44 files changed

+1231
-980
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1231
-980
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2023 - 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.ai.bedrock;
17+
18+
import java.util.HashMap;
19+
20+
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
21+
import org.springframework.ai.chat.metadata.EmptyUsage;
22+
import org.springframework.ai.chat.metadata.Usage;
23+
24+
import software.amazon.awssdk.services.bedrockruntime.model.ConverseMetrics;
25+
import software.amazon.awssdk.services.bedrockruntime.model.ConverseResponse;
26+
import software.amazon.awssdk.services.bedrockruntime.model.ConverseStreamMetadataEvent;
27+
import software.amazon.awssdk.services.bedrockruntime.model.ConverseStreamMetrics;
28+
29+
/**
30+
* {@link ChatResponseMetadata} implementation for {@literal Amazon Bedrock}.
31+
*
32+
* @author Wei Jiang
33+
* @since 1.0.0
34+
*/
35+
public class BedrockChatResponseMetadata extends HashMap<String, Object> implements ChatResponseMetadata {
36+
37+
protected static final String AI_METADATA_STRING = "{ @type: %1$s, id: %2$s, usage: %3$s, latency: %4$sms}";
38+
39+
private final String id;
40+
41+
private final Usage usage;
42+
43+
private final Long latencyMs;
44+
45+
public static BedrockChatResponseMetadata from(ConverseResponse response) {
46+
String requestId = response.responseMetadata().requestId();
47+
48+
BedrockUsage usage = BedrockUsage.from(response.usage());
49+
50+
ConverseMetrics metrics = response.metrics();
51+
52+
return new BedrockChatResponseMetadata(requestId, usage, metrics.latencyMs());
53+
}
54+
55+
public static BedrockChatResponseMetadata from(ConverseStreamMetadataEvent converseStreamMetadataEvent) {
56+
BedrockUsage usage = BedrockUsage.from(converseStreamMetadataEvent.usage());
57+
58+
ConverseStreamMetrics metrics = converseStreamMetadataEvent.metrics();
59+
60+
return new BedrockChatResponseMetadata(null, usage, metrics.latencyMs());
61+
}
62+
63+
protected BedrockChatResponseMetadata(String id, BedrockUsage usage, Long latencyMs) {
64+
this.id = id;
65+
this.usage = usage;
66+
this.latencyMs = latencyMs;
67+
}
68+
69+
public String getId() {
70+
return this.id;
71+
}
72+
73+
public Long getLatencyMs() {
74+
return latencyMs;
75+
}
76+
77+
@Override
78+
public Usage getUsage() {
79+
Usage usage = this.usage;
80+
return usage != null ? usage : new EmptyUsage();
81+
}
82+
83+
@Override
84+
public String toString() {
85+
return AI_METADATA_STRING.formatted(getClass().getName(), getId(), getUsage(), getLatencyMs());
86+
}
87+
88+
}

models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/BedrockUsage.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,49 @@
1919
import org.springframework.ai.chat.metadata.Usage;
2020
import org.springframework.util.Assert;
2121

22+
import software.amazon.awssdk.services.bedrockruntime.model.TokenUsage;
23+
2224
/**
2325
* {@link Usage} implementation for Bedrock API.
2426
*
2527
* @author Christian Tzolov
28+
* @author Wei Jiang
2629
* @since 0.8.0
2730
*/
2831
public class BedrockUsage implements Usage {
2932

3033
public static BedrockUsage from(AmazonBedrockInvocationMetrics usage) {
31-
return new BedrockUsage(usage);
34+
return new BedrockUsage(usage.inputTokenCount().longValue(), usage.outputTokenCount().longValue());
3235
}
3336

34-
private final AmazonBedrockInvocationMetrics usage;
37+
public static BedrockUsage from(TokenUsage usage) {
38+
Assert.notNull(usage, "'TokenUsage' must not be null.");
3539

36-
protected BedrockUsage(AmazonBedrockInvocationMetrics usage) {
37-
Assert.notNull(usage, "OpenAI Usage must not be null");
38-
this.usage = usage;
40+
return new BedrockUsage(usage.inputTokens().longValue(), usage.outputTokens().longValue());
3941
}
4042

41-
protected AmazonBedrockInvocationMetrics getUsage() {
42-
return this.usage;
43+
private final Long inputTokens;
44+
45+
private final Long outputTokens;
46+
47+
protected BedrockUsage(Long inputTokens, Long outputTokens) {
48+
this.inputTokens = inputTokens;
49+
this.outputTokens = outputTokens;
4350
}
4451

4552
@Override
4653
public Long getPromptTokens() {
47-
return getUsage().inputTokenCount().longValue();
54+
return inputTokens;
4855
}
4956

5057
@Override
5158
public Long getGenerationTokens() {
52-
return getUsage().outputTokenCount().longValue();
59+
return outputTokens;
5360
}
5461

5562
@Override
5663
public String toString() {
57-
return getUsage().toString();
64+
return "BedrockUsage [inputTokens=" + inputTokens + ", outputTokens=" + outputTokens + "]";
5865
}
5966

6067
}

models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
import org.springframework.util.Assert;
3434

3535
/**
36+
* @deprecated Use {@link BedrockConverseApi} instead.
3637
* @author Christian Tzolov
3738
* @author Wei Jiang
3839
* @since 0.8.0
3940
*/
4041
// @formatter:off
42+
@Deprecated
4143
public class AnthropicChatBedrockApi extends
4244
AbstractBedrockApi<AnthropicChatRequest, AnthropicChatResponse, AnthropicChatResponse> {
4345

models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic3/Anthropic3ChatOptions.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ public class Anthropic3ChatOptions implements ChatOptions {
6262
*/
6363
private @JsonProperty("stop_sequences") List<String> stopSequences;
6464

65-
/**
66-
* The version of the generative to use. The default value is bedrock-2023-05-31.
67-
*/
68-
private @JsonProperty("anthropic_version") String anthropicVersion;
6965
// @formatter:on
7066

7167
public static Builder builder() {
@@ -101,11 +97,6 @@ public Builder withStopSequences(List<String> stopSequences) {
10197
return this;
10298
}
10399

104-
public Builder withAnthropicVersion(String anthropicVersion) {
105-
this.options.setAnthropicVersion(anthropicVersion);
106-
return this;
107-
}
108-
109100
public Anthropic3ChatOptions build() {
110101
return this.options;
111102
}
@@ -155,21 +146,12 @@ public void setStopSequences(List<String> stopSequences) {
155146
this.stopSequences = stopSequences;
156147
}
157148

158-
public String getAnthropicVersion() {
159-
return this.anthropicVersion;
160-
}
161-
162-
public void setAnthropicVersion(String anthropicVersion) {
163-
this.anthropicVersion = anthropicVersion;
164-
}
165-
166149
public static Anthropic3ChatOptions fromOptions(Anthropic3ChatOptions fromOptions) {
167150
return builder().withTemperature(fromOptions.getTemperature())
168151
.withMaxTokens(fromOptions.getMaxTokens())
169152
.withTopK(fromOptions.getTopK())
170153
.withTopP(fromOptions.getTopP())
171154
.withStopSequences(fromOptions.getStopSequences())
172-
.withAnthropicVersion(fromOptions.getAnthropicVersion())
173155
.build();
174156
}
175157

0 commit comments

Comments
 (0)