Skip to content

Commit

Permalink
feat: Support Gen AI attributes for Amazon Nova foundational model (#300
Browse files Browse the repository at this point in the history
)

*Description of changes:*
Added GenAI inference parameters auto instrumentation support for Amazon
Nova.

Contract tests:
<img width="924" alt="image"
src="https://github.com/user-attachments/assets/5e7544d7-3d37-432f-a1d7-25690f12453f"
/>

<img width="889" alt="image"
src="https://github.com/user-attachments/assets/408f4c7a-5d69-41d1-800a-b88f8db7aef0"
/>

By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
  • Loading branch information
liustve authored Dec 17, 2024
1 parent 264493e commit 93c1588
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def extract_attributes(self, attributes: _AttributeMapT):

if "amazon.titan" in model_id:
self._extract_titan_attributes(attributes, request_body)
if "amazon.nova" in model_id:
self._extract_nova_attributes(attributes, request_body)
elif "anthropic.claude" in model_id:
self._extract_claude_attributes(attributes, request_body)
elif "meta.llama" in model_id:
Expand All @@ -288,6 +290,12 @@ def _extract_titan_attributes(self, attributes, request_body):
self._set_if_not_none(attributes, GEN_AI_REQUEST_TOP_P, config.get("topP"))
self._set_if_not_none(attributes, GEN_AI_REQUEST_MAX_TOKENS, config.get("maxTokenCount"))

def _extract_nova_attributes(self, attributes, request_body):
config = request_body.get("inferenceConfig", {})
self._set_if_not_none(attributes, GEN_AI_REQUEST_TEMPERATURE, config.get("temperature"))
self._set_if_not_none(attributes, GEN_AI_REQUEST_TOP_P, config.get("top_p"))
self._set_if_not_none(attributes, GEN_AI_REQUEST_MAX_TOKENS, config.get("max_new_tokens"))

def _extract_claude_attributes(self, attributes, request_body):
self._set_if_not_none(attributes, GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_tokens"))
self._set_if_not_none(attributes, GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature"))
Expand Down Expand Up @@ -324,6 +332,7 @@ def _set_if_not_none(attributes, key, value):
if value is not None:
attributes[key] = value

# pylint: disable=too-many-branches
def on_success(self, span: Span, result: Dict[str, Any]):
model_id = self._call_context.params.get(_MODEL_ID)

Expand All @@ -342,6 +351,8 @@ def on_success(self, span: Span, result: Dict[str, Any]):
response_body = json.loads(telemetry_content.decode("utf-8"))
if "amazon.titan" in model_id:
self._handle_amazon_titan_response(span, response_body)
if "amazon.nova" in model_id:
self._handle_amazon_nova_response(span, response_body)
elif "anthropic.claude" in model_id:
self._handle_anthropic_claude_response(span, response_body)
elif "meta.llama" in model_id:
Expand Down Expand Up @@ -375,6 +386,17 @@ def _handle_amazon_titan_response(self, span: Span, response_body: Dict[str, Any
if "completionReason" in result:
span.set_attribute(GEN_AI_RESPONSE_FINISH_REASONS, [result["completionReason"]])

# pylint: disable=no-self-use
def _handle_amazon_nova_response(self, span: Span, response_body: Dict[str, Any]):
if "usage" in response_body:
usage = response_body["usage"]
if "inputTokens" in usage:
span.set_attribute(GEN_AI_USAGE_INPUT_TOKENS, usage["inputTokens"])
if "outputTokens" in usage:
span.set_attribute(GEN_AI_USAGE_OUTPUT_TOKENS, usage["outputTokens"])
if "stopReason" in response_body:
span.set_attribute(GEN_AI_RESPONSE_FINISH_REASONS, [response_body["stopReason"]])

# pylint: disable=no-self-use
def _handle_anthropic_claude_response(self, span: Span, response_body: Dict[str, Any]):
if "usage" in response_body:
Expand Down
Loading

0 comments on commit 93c1588

Please sign in to comment.