Skip to content

Commit 789bf86

Browse files
authored
botocore: handle system messages events (#3266)
* botocore: handle system event messages * Add CHANGELOG * Please pylint
1 parent 1623dc0 commit 789bf86

19 files changed

+2345
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
- `opentelemetry-instrumentation-botocore` Add support for GenAI user events and lazy initialize tracer
1717
([#3258](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3258))
18+
- `opentelemetry-instrumentation-botocore` Add support for GenAI system events
19+
([#3266](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3266))
1820

1921
### Fixed
2022

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,23 @@ def _set_if_not_none(attributes, key, value):
209209
attributes[key] = value
210210

211211
def _get_request_messages(self):
212+
"""Extracts and normalize system and user / assistant messages"""
212213
input_text = None
214+
if system := self._call_context.params.get("system", []):
215+
system_messages = [{"role": "system", "content": system}]
216+
else:
217+
system_messages = []
218+
213219
if not (messages := self._call_context.params.get("messages", [])):
214220
if body := self._call_context.params.get("body"):
215221
decoded_body = json.loads(body)
222+
if system := decoded_body.get("system"):
223+
if isinstance(system, str):
224+
content = [{"text": system}]
225+
else:
226+
content = system
227+
system_messages = [{"role": "system", "content": content}]
228+
216229
messages = decoded_body.get("messages", [])
217230
if not messages:
218231
# transform old school amazon titan invokeModel api to messages
@@ -221,7 +234,7 @@ def _get_request_messages(self):
221234
{"role": "user", "content": [{"text": input_text}]}
222235
]
223236

224-
return messages
237+
return system_messages + messages
225238

226239
def before_service_call(
227240
self, span: Span, instrumentor_context: _BotocoreInstrumentorContext

instrumentation/opentelemetry-instrumentation-botocore/tests/bedrock_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ def assert_stream_completion_attributes(
161161

162162
def assert_equal_or_not_present(value, attribute_name, span):
163163
if value is not None:
164-
assert value == span.attributes[attribute_name]
164+
assert value == span.attributes[attribute_name], span.attributes[
165+
attribute_name
166+
]
165167
else:
166168
assert attribute_name not in span.attributes, attribute_name
167169

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
interactions:
2+
- request:
3+
body: |-
4+
{
5+
"system": [
6+
{
7+
"text": "You are a friendly app"
8+
}
9+
],
10+
"messages": [
11+
{
12+
"role": "user",
13+
"content": [
14+
{
15+
"text": "Say this is a test"
16+
}
17+
]
18+
},
19+
{
20+
"role": "assistant",
21+
"content": [
22+
{
23+
"text": "This is a test"
24+
}
25+
]
26+
},
27+
{
28+
"role": "user",
29+
"content": [
30+
{
31+
"text": "Say again this is a test"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
headers:
38+
Content-Length:
39+
- '258'
40+
Content-Type:
41+
- application/json
42+
User-Agent:
43+
- Boto3/1.35.56 md/Botocore#1.35.56 ua/2.0 os/linux#6.1.0-1034-oem md/arch#x86_64
44+
lang/python#3.10.12 md/pyimpl#CPython cfg/retry-mode#legacy Botocore/1.35.56
45+
X-Amz-Date:
46+
- 20250213T113027Z
47+
X-Amz-Security-Token:
48+
- test_aws_security_token
49+
X-Amzn-Trace-Id:
50+
- Root=1-d9112d64-56325c43023ba04895b18fc1;Parent=d56bf41aee9dd9b2;Sampled=1
51+
amz-sdk-invocation-id:
52+
- 4e1fd77b-1b21-4b3a-9b96-d74fb74ede7c
53+
amz-sdk-request:
54+
- attempt=1
55+
authorization:
56+
- Bearer test_aws_authorization
57+
method: POST
58+
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-v2/converse
59+
response:
60+
body:
61+
string: |-
62+
{
63+
"metrics": {
64+
"latencyMs": 489
65+
},
66+
"output": {
67+
"message": {
68+
"content": [
69+
{
70+
"text": "This is a test"
71+
}
72+
],
73+
"role": "assistant"
74+
}
75+
},
76+
"stopReason": "end_turn",
77+
"usage": {
78+
"inputTokens": 37,
79+
"outputTokens": 8,
80+
"totalTokens": 45
81+
}
82+
}
83+
headers:
84+
Connection:
85+
- keep-alive
86+
Content-Type:
87+
- application/json
88+
Date:
89+
- Thu, 13 Feb 2025 11:30:28 GMT
90+
Set-Cookie: test_set_cookie
91+
x-amzn-RequestId:
92+
- 67f0b4ef-e481-4c12-853b-d8e992395129
93+
status:
94+
code: 200
95+
message: OK
96+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
interactions:
2+
- request:
3+
body: |-
4+
{
5+
"system": [
6+
{
7+
"text": "You are a friendly app"
8+
}
9+
],
10+
"messages": [
11+
{
12+
"role": "user",
13+
"content": [
14+
{
15+
"text": "Say this is a test"
16+
}
17+
]
18+
},
19+
{
20+
"role": "assistant",
21+
"content": [
22+
{
23+
"text": "This is a test"
24+
}
25+
]
26+
},
27+
{
28+
"role": "user",
29+
"content": [
30+
{
31+
"text": "Say again this is a test"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
headers:
38+
Content-Length:
39+
- '258'
40+
Content-Type:
41+
- application/json
42+
User-Agent:
43+
- Boto3/1.35.56 md/Botocore#1.35.56 ua/2.0 os/linux#6.1.0-1034-oem md/arch#x86_64
44+
lang/python#3.10.12 md/pyimpl#CPython cfg/retry-mode#legacy Botocore/1.35.56
45+
X-Amz-Date:
46+
- 20250213T134717Z
47+
X-Amz-Security-Token:
48+
- test_aws_security_token
49+
X-Amzn-Trace-Id:
50+
- Root=1-014325aa-ed2dea786b6b5b895661a1fd;Parent=540790d110580421;Sampled=1
51+
amz-sdk-invocation-id:
52+
- 22820432-2412-4351-98af-8c70c71c84a9
53+
amz-sdk-request:
54+
- attempt=1
55+
authorization:
56+
- Bearer test_aws_authorization
57+
method: POST
58+
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-v2/converse-stream
59+
response:
60+
body:
61+
string: !!binary |
62+
AAAAkwAAAFJ24bJxCzpldmVudC10eXBlBwAMbWVzc2FnZVN0YXJ0DTpjb250ZW50LXR5cGUHABBh
63+
cHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsicCI6ImFiY2RlZmdoaWprbG1u
64+
b3BxcnN0dXYiLCJyb2xlIjoiYXNzaXN0YW50In2AaQZuAAAAzQAAAFeBqDdUCzpldmVudC10eXBl
65+
BwARY29udGVudEJsb2NrRGVsdGENOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1l
66+
c3NhZ2UtdHlwZQcABWV2ZW50eyJjb250ZW50QmxvY2tJbmRleCI6MCwiZGVsdGEiOnsidGV4dCI6
67+
IlRoaXMifSwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFS
68+
U1RVViJ9qHD4cgAAALQAAABXdWq16gs6ZXZlbnQtdHlwZQcAEWNvbnRlbnRCbG9ja0RlbHRhDTpj
69+
b250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiY29u
70+
dGVudEJsb2NrSW5kZXgiOjAsImRlbHRhIjp7InRleHQiOiIgaXMifSwicCI6ImFiY2RlZmdoaWpr
71+
bG1ub3BxcnN0dXZ3eCJ9dhKCRAAAALAAAABXgOoTKgs6ZXZlbnQtdHlwZQcAEWNvbnRlbnRCbG9j
72+
a0RlbHRhDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVl
73+
dmVudHsiY29udGVudEJsb2NrSW5kZXgiOjAsImRlbHRhIjp7InRleHQiOiIgYSJ9LCJwIjoiYWJj
74+
ZGVmZ2hpamtsbW5vcHFyc3R1In0IN1EQAAAAtQAAAFdICpxaCzpldmVudC10eXBlBwARY29udGVu
75+
dEJsb2NrRGVsdGENOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlw
76+
ZQcABWV2ZW50eyJjb250ZW50QmxvY2tJbmRleCI6MCwiZGVsdGEiOnsidGV4dCI6IiB0ZXN0In0s
77+
InAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2dyJ9V81m8wAAAIkAAABWW9z5Sws6ZXZlbnQtdHlw
78+
ZQcAEGNvbnRlbnRCbG9ja1N0b3ANOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1l
79+
c3NhZ2UtdHlwZQcABWV2ZW50eyJjb250ZW50QmxvY2tJbmRleCI6MCwicCI6ImFiY2RlIn3nHPCv
80+
AAAAoAAAAFEJaSGdCzpldmVudC10eXBlBwALbWVzc2FnZVN0b3ANOmNvbnRlbnQtdHlwZQcAEGFw
81+
cGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJwIjoiYWJjZGVmZ2hpamtsbW5v
82+
cHFyc3R1dnd4eXpBQkNERSIsInN0b3BSZWFzb24iOiJlbmRfdHVybiJ9p5BdEgAAAMsAAABOaoNq
83+
NAs6ZXZlbnQtdHlwZQcACG1ldGFkYXRhDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29u
84+
DTptZXNzYWdlLXR5cGUHAAVldmVudHsibWV0cmljcyI6eyJsYXRlbmN5TXMiOjM2MX0sInAiOiJh
85+
YmNkZWZnaGlqa2wiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MzcsIm91dHB1dFRva2VucyI6OCwi
86+
dG90YWxUb2tlbnMiOjQ1fX1Nq2WY
87+
headers:
88+
Connection:
89+
- keep-alive
90+
Content-Type:
91+
- application/vnd.amazon.eventstream
92+
Date:
93+
- Thu, 13 Feb 2025 13:47:17 GMT
94+
Set-Cookie: test_set_cookie
95+
Transfer-Encoding:
96+
- chunked
97+
x-amzn-RequestId:
98+
- e443d332-cba6-4076-a4f6-86d6321eada3
99+
status:
100+
code: 200
101+
message: OK
102+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
interactions:
2+
- request:
3+
body: |-
4+
{
5+
"system": [
6+
{
7+
"text": "You are a friendly app"
8+
}
9+
],
10+
"messages": [
11+
{
12+
"role": "user",
13+
"content": [
14+
{
15+
"text": "Say this is a test"
16+
}
17+
]
18+
},
19+
{
20+
"role": "assistant",
21+
"content": [
22+
{
23+
"text": "This is a test"
24+
}
25+
]
26+
},
27+
{
28+
"role": "user",
29+
"content": [
30+
{
31+
"text": "Say again this is a test"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
headers:
38+
Content-Length:
39+
- '258'
40+
Content-Type:
41+
- application/json
42+
User-Agent:
43+
- Boto3/1.35.56 md/Botocore#1.35.56 ua/2.0 os/linux#6.1.0-1034-oem md/arch#x86_64
44+
lang/python#3.10.12 md/pyimpl#CPython cfg/retry-mode#legacy Botocore/1.35.56
45+
X-Amz-Date:
46+
- 20250213T134611Z
47+
X-Amz-Security-Token:
48+
- test_aws_security_token
49+
X-Amzn-Trace-Id:
50+
- Root=1-deb34c78-8ab87e14665141b9e132396b;Parent=8e997adc8051f5a6;Sampled=1
51+
amz-sdk-invocation-id:
52+
- 81e436d8-7c5d-4025-a9e5-de505ccb9b51
53+
amz-sdk-request:
54+
- attempt=1
55+
authorization:
56+
- Bearer test_aws_authorization
57+
method: POST
58+
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-v2/converse-stream
59+
response:
60+
body:
61+
string: !!binary |
62+
AAAArAAAAFJVkJ0mCzpldmVudC10eXBlBwAMbWVzc2FnZVN0YXJ0DTpjb250ZW50LXR5cGUHABBh
63+
cHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsicCI6ImFiY2RlZmdoaWprbG1u
64+
b3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVIiwicm9sZSI6ImFzc2lzdGFudCJ9mBqg
65+
YwAAANQAAABX7FjCpws6ZXZlbnQtdHlwZQcAEWNvbnRlbnRCbG9ja0RlbHRhDTpjb250ZW50LXR5
66+
cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiY29udGVudEJsb2Nr
67+
SW5kZXgiOjAsImRlbHRhIjp7InRleHQiOiJUaGlzIn0sInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJz
68+
dHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyIn2n2T4pAAAArQAAAFcYmkAZCzpl
69+
dmVudC10eXBlBwARY29udGVudEJsb2NrRGVsdGENOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9u
70+
L2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJjb250ZW50QmxvY2tJbmRleCI6MCwiZGVsdGEi
71+
OnsidGV4dCI6IiBpcyJ9LCJwIjoiYWJjZGVmZ2hpamtsbW5vcHEifYkheRMAAADQAAAAVxnYZGcL
72+
OmV2ZW50LXR5cGUHABFjb250ZW50QmxvY2tEZWx0YQ06Y29udGVudC10eXBlBwAQYXBwbGljYXRp
73+
b24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImNvbnRlbnRCbG9ja0luZGV4IjowLCJkZWx0
74+
YSI6eyJ0ZXh0IjoiIGEifSwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJ
75+
SktMTU5PUFFSU1RVVldYWVowIn3K4xpaAAAA0wAAAFdeeB63CzpldmVudC10eXBlBwARY29udGVu
76+
dEJsb2NrRGVsdGENOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlw
77+
ZQcABWV2ZW50eyJjb250ZW50QmxvY2tJbmRleCI6MCwiZGVsdGEiOnsidGV4dCI6IiB0ZXN0In0s
78+
InAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFla
79+
MCJ916eYywAAALkAAABW+v1BzQs6ZXZlbnQtdHlwZQcAEGNvbnRlbnRCbG9ja1N0b3ANOmNvbnRl
80+
bnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJjb250ZW50
81+
QmxvY2tJbmRleCI6MCwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktM
82+
TU5PUFFSU1RVVldYWVowIn2IAETUAAAAhgAAAFFH6Ps5CzpldmVudC10eXBlBwALbWVzc2FnZVN0
83+
b3ANOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50
84+
eyJwIjoiYWJjZGUiLCJzdG9wUmVhc29uIjoiZW5kX3R1cm4ifSknYaEAAAD3AAAATg5SP7MLOmV2
85+
ZW50LXR5cGUHAAhtZXRhZGF0YQ06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVz
86+
c2FnZS10eXBlBwAFZXZlbnR7Im1ldHJpY3MiOnsibGF0ZW5jeU1zIjo1MDh9LCJwIjoiYWJjZGVm
87+
Z2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjMiLCJ1c2Fn
88+
ZSI6eyJpbnB1dFRva2VucyI6MzcsIm91dHB1dFRva2VucyI6OCwidG90YWxUb2tlbnMiOjQ1fX0o
89+
MQhc
90+
headers:
91+
Connection:
92+
- keep-alive
93+
Content-Type:
94+
- application/vnd.amazon.eventstream
95+
Date:
96+
- Thu, 13 Feb 2025 13:46:12 GMT
97+
Set-Cookie: test_set_cookie
98+
Transfer-Encoding:
99+
- chunked
100+
x-amzn-RequestId:
101+
- 829dbcea-d3df-4781-be84-c1c2d5c420bd
102+
status:
103+
code: 200
104+
message: OK
105+
version: 1

0 commit comments

Comments
 (0)