Skip to content

Commit bbb1caf

Browse files
authored
fix(sdk): support bedrock (#9)
1 parent ddb3281 commit bbb1caf

5 files changed

Lines changed: 71 additions & 3 deletions

File tree

sample-app/Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ gem "ruby-openai"
66
gem "traceloop-sdk"
77

88
gem "gemini-ai", "~> 4.1"
9+
10+
gem "aws-sdk-bedrockruntime", "~> 1.14"

sample-app/Gemfile.lock

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ GEM
33
specs:
44
addressable (2.8.7)
55
public_suffix (>= 2.0.2, < 7.0)
6+
aws-eventstream (1.3.0)
7+
aws-partitions (1.947.0)
8+
aws-sdk-bedrockruntime (1.14.0)
9+
aws-sdk-core (~> 3, >= 3.199.0)
10+
aws-sigv4 (~> 1.1)
11+
aws-sdk-core (3.199.0)
12+
aws-eventstream (~> 1, >= 1.3.0)
13+
aws-partitions (~> 1, >= 1.651.0)
14+
aws-sigv4 (~> 1.8)
15+
jmespath (~> 1, >= 1.6.1)
16+
aws-sigv4 (1.8.0)
17+
aws-eventstream (~> 1, >= 1.0.2)
618
base64 (0.1.1)
719
ethon (0.16.0)
820
ffi (>= 1.15.0)
@@ -34,6 +46,7 @@ GEM
3446
multi_json (~> 1.11)
3547
os (>= 0.9, < 2.0)
3648
signet (>= 0.16, < 2.a)
49+
jmespath (1.6.2)
3750
jwt (2.8.2)
3851
base64
3952
multi_json (1.15.0)
@@ -70,7 +83,7 @@ GEM
7083
faraday (>= 0.17.5, < 3.a)
7184
jwt (>= 1.5, < 3.0)
7285
multi_json (~> 1.10)
73-
traceloop-sdk (0.0.5)
86+
traceloop-sdk (0.0.8)
7487
opentelemetry-exporter-otlp (~> 0.26.1)
7588
opentelemetry-sdk (~> 1.3.1)
7689
opentelemetry-semantic_conventions_ai (~> 0.0.3)
@@ -81,6 +94,7 @@ PLATFORMS
8194
arm64-darwin-23
8295

8396
DEPENDENCIES
97+
aws-sdk-bedrockruntime (~> 1.14)
8498
gemini-ai (~> 4.1)
8599
ruby-openai
86100
traceloop-sdk

sample-app/bedrock.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'aws-sdk-bedrockruntime'
2+
require "traceloop/sdk"
3+
4+
traceloop = Traceloop::SDK::Traceloop.new
5+
6+
model = "anthropic.claude-3-sonnet-20240229-v1:0"
7+
8+
traceloop.llm_call(provider="bedrock", model=model) do |tracer|
9+
tracer.log_prompt(user_prompt="Tell me a joke about OpenTelemetry")
10+
response = Aws::BedrockRuntime::Client.new.invoke_model({
11+
model_id: model,
12+
content_type: "application/json",
13+
accept: "*/*",
14+
body: {
15+
messages: [{ role: "user", content: "Tell me a joke about OpenTelemetry" }],
16+
max_tokens: 4096,
17+
anthropic_version: "bedrock-2023-05-31"
18+
}.to_json
19+
})
20+
tracer.log_response(response)
21+
22+
body = JSON.parse(response.body.read())
23+
puts body
24+
end

traceloop-sdk/lib/traceloop/sdk.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ def log_prompt(system_prompt="", user_prompt)
4646
end
4747

4848
def log_response(response)
49+
if response.respond_to?(:body)
50+
log_bedrock_response(response)
4951
# This is Gemini specific, see -
5052
# https://github.com/gbaptista/gemini-ai?tab=readme-ov-file#generate_content
51-
if response.has_key?("candidates")
53+
elsif response.has_key?("candidates")
5254
log_gemini_response(response)
5355
else
5456
log_openai_response(response)
@@ -66,6 +68,32 @@ def log_gemini_response(response)
6668
})
6769
end
6870

71+
def log_bedrock_response(response)
72+
body = JSON.parse(response.body.read())
73+
74+
@span.add_attributes({
75+
OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_RESPONSE_MODEL => body.dig("model"),
76+
})
77+
if body.has_key?("usage")
78+
input_tokens = body.dig("usage", "input_tokens")
79+
output_tokens = body.dig("usage", "output_tokens")
80+
81+
@span.add_attributes({
82+
OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_USAGE_TOTAL_TOKENS => input_tokens + output_tokens,
83+
OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_USAGE_COMPLETION_TOKENS => output_tokens,
84+
OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_USAGE_PROMPT_TOKENS => input_tokens,
85+
})
86+
end
87+
if body.has_key?("content")
88+
@span.add_attributes({
89+
"#{OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_COMPLETIONS}.0.role" => body.dig("role"),
90+
"#{OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_COMPLETIONS}.0.content" => body.dig("content").first.dig("text")
91+
})
92+
end
93+
94+
response.body.rewind()
95+
end
96+
6997
def log_openai_response(response)
7098
@span.add_attributes({
7199
OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_RESPONSE_MODEL => response.dig("model"),

traceloop-sdk/traceloop-sdk.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |spec|
22
spec.name = 'traceloop-sdk'
3-
spec.version = '0.0.5'
3+
spec.version = '0.0.8'
44
spec.authors = ["Traceloop"]
55
spec.email = ['dev@traceloop.com']
66

0 commit comments

Comments
 (0)