Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(llmobs): submit llmobs payloads from gemini integration #10619

Merged
merged 39 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7591b5d
WIP Gemini Integration
Yun-Kim Sep 3, 2024
f4c62a5
Support tracing streamed responses
Yun-Kim Sep 4, 2024
7aed48b
fmt, refactor nesting
Yun-Kim Sep 4, 2024
c8e8c57
fmt, release note draft
Yun-Kim Sep 4, 2024
77ee9f5
Merge branch 'main' into yunkim/gemini-integration
Yun-Kim Sep 4, 2024
a95f2a6
Extract api key, model name
Yun-Kim Sep 5, 2024
364bc73
Add tests
Yun-Kim Sep 9, 2024
ccc3349
fmt
Yun-Kim Sep 9, 2024
4344a6e
Docs
Yun-Kim Sep 9, 2024
8531633
More docs
Yun-Kim Sep 9, 2024
d449f01
fmt
Yun-Kim Sep 9, 2024
4c6003a
Suitespec
Yun-Kim Sep 9, 2024
902611a
Remove from gitlab, add to circleci
Yun-Kim Sep 9, 2024
648a3ae
spellcheck
Yun-Kim Sep 9, 2024
4b79cbf
Migrate tests back to gitlab
Yun-Kim Sep 10, 2024
e622d35
fix spelling
Yun-Kim Sep 10, 2024
1791545
Codeowners
Yun-Kim Sep 10, 2024
c1ba316
Merge branch 'main' into yunkim/gemini-integration
Yun-Kim Sep 10, 2024
a6ab1dd
Move suite to llmobs gitlab
Yun-Kim Sep 10, 2024
f9c4cff
Wip llmobs integration for gemini
Yun-Kim Sep 10, 2024
1ddb560
fmt, remove breakpoint
Yun-Kim Sep 10, 2024
f32abd5
Add tests
Yun-Kim Sep 10, 2024
91f8ee3
Address comments, fix snapshots
Yun-Kim Sep 10, 2024
f2c3331
fix snapshots
Yun-Kim Sep 10, 2024
886cf7a
Merge branch 'yunkim/gemini-integration' into yunkim/llmobs-gemini
Yun-Kim Sep 10, 2024
99b13ac
Refactor
Yun-Kim Sep 10, 2024
62d4849
fmt
Yun-Kim Sep 10, 2024
f7455a9
fmt
Yun-Kim Sep 10, 2024
da6b967
typing
Yun-Kim Sep 10, 2024
d7b73bb
fmt, address PR comments
Yun-Kim Sep 11, 2024
bceda68
Merge branch 'yunkim/gemini-integration' into yunkim/llmobs-gemini
Yun-Kim Sep 11, 2024
37830d4
Do not assume default roles if not provided
Yun-Kim Sep 11, 2024
ca44592
avoid silent error
Yun-Kim Sep 11, 2024
7c57b59
fmt
Yun-Kim Sep 11, 2024
b8a4bf5
Merge branch 'yunkim/gemini-integration' into yunkim/llmobs-gemini
Yun-Kim Sep 11, 2024
eecda47
typing
Yun-Kim Sep 11, 2024
b97cc13
Merge branch 'yunkim/gemini-integration' into yunkim/llmobs-gemini
Yun-Kim Sep 11, 2024
d6379e6
merge conflict
Yun-Kim Sep 11, 2024
cc859e6
Merge branch 'main' into yunkim/llmobs-gemini
Yun-Kim Sep 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,16 @@ ddtrace/contrib/internal/botocore/services/bedrock.py @DataDog/ml-observabilit
ddtrace/contrib/botocore/services/bedrock.py @DataDog/ml-observability
ddtrace/contrib/internal/anthropic @DataDog/ml-observability
ddtrace/contrib/anthropic @DataDog/ml-observability
ddtrace/contrib/internal/google_generativeai @DataDog/ml-observability
ddtrace/contrib/google_generativeai @DataDog/ml-observability
tests/llmobs @DataDog/ml-observability
tests/contrib/openai @DataDog/ml-observability
tests/contrib/langchain @DataDog/ml-observability
tests/contrib/botocore/test_bedrock.py @DataDog/ml-observability
tests/contrib/botocore/test_bedrock_llmobs.py @DataDog/ml-observability
tests/contrib/botocore/bedrock_cassettes @DataDog/ml-observability
tests/contrib/anthropic @DataDog/ml-observability
tests/contrib/google_generativeai @DataDog/ml-observability
.gitlab/tests/llmobs.yml @DataDog/ml-observability

# Remote Config
Expand Down
4 changes: 4 additions & 0 deletions .gitlab/tests/llmobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ anthropic:
variables:
SUITE_NAME: "anthropic"

google_generativeai:
extends: .test_base_riot_snapshot
variables:
SUITE_NAME: "google_generativeai"
48 changes: 48 additions & 0 deletions .riot/requirements/1e15a25.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/1e15a25.in
#
annotated-types==0.7.0
attrs==24.2.0
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.3.2
coverage[toml]==7.6.1
google-ai-generativelanguage==0.6.9
google-api-core[grpc]==2.19.2
google-api-python-client==2.145.0
google-auth==2.34.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.0
googleapis-common-protos==1.65.0
grpcio==1.66.1
grpcio-status==1.66.1
httplib2==0.22.0
hypothesis==6.45.0
idna==3.8
iniconfig==2.0.0
mock==5.1.0
opentracing==2.4.0
packaging==24.1
pillow==10.4.0
pluggy==1.5.0
proto-plus==1.24.0
protobuf==5.28.0
pyasn1==0.6.0
pyasn1-modules==0.4.0
pydantic==2.9.1
pydantic-core==2.23.3
pyparsing==3.1.4
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-cov==5.0.0
pytest-mock==3.14.0
requests==2.32.3
rsa==4.9
sortedcontainers==2.4.0
tqdm==4.66.5
typing-extensions==4.12.2
uritemplate==4.1.1
urllib3==2.2.2
50 changes: 50 additions & 0 deletions .riot/requirements/1f54e6b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/1f54e6b.in
#
annotated-types==0.7.0
attrs==24.2.0
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.3.2
coverage[toml]==7.6.1
exceptiongroup==1.2.2
google-ai-generativelanguage==0.6.9
google-api-core[grpc]==2.19.2
google-api-python-client==2.145.0
google-auth==2.34.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.0
googleapis-common-protos==1.65.0
grpcio==1.66.1
grpcio-status==1.66.1
httplib2==0.22.0
hypothesis==6.45.0
idna==3.8
iniconfig==2.0.0
mock==5.1.0
opentracing==2.4.0
packaging==24.1
pillow==10.4.0
pluggy==1.5.0
proto-plus==1.24.0
protobuf==5.28.0
pyasn1==0.6.0
pyasn1-modules==0.4.0
pydantic==2.9.1
pydantic-core==2.23.3
pyparsing==3.1.4
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-cov==5.0.0
pytest-mock==3.14.0
requests==2.32.3
rsa==4.9
sortedcontainers==2.4.0
tomli==2.0.1
tqdm==4.66.5
typing-extensions==4.12.2
uritemplate==4.1.1
urllib3==2.2.2
48 changes: 48 additions & 0 deletions .riot/requirements/e8247d6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/e8247d6.in
#
annotated-types==0.7.0
attrs==24.2.0
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.3.2
coverage[toml]==7.6.1
google-ai-generativelanguage==0.6.9
google-api-core[grpc]==2.19.2
google-api-python-client==2.145.0
google-auth==2.34.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.0
googleapis-common-protos==1.65.0
grpcio==1.66.1
grpcio-status==1.66.1
httplib2==0.22.0
hypothesis==6.45.0
idna==3.8
iniconfig==2.0.0
mock==5.1.0
opentracing==2.4.0
packaging==24.1
pillow==10.4.0
pluggy==1.5.0
proto-plus==1.24.0
protobuf==5.28.0
pyasn1==0.6.0
pyasn1-modules==0.4.0
pydantic==2.9.1
pydantic-core==2.23.3
pyparsing==3.1.4
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-cov==5.0.0
pytest-mock==3.14.0
requests==2.32.3
rsa==4.9
sortedcontainers==2.4.0
tqdm==4.66.5
typing-extensions==4.12.2
uritemplate==4.1.1
urllib3==2.2.2
50 changes: 50 additions & 0 deletions .riot/requirements/ebe4ea5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/ebe4ea5.in
#
annotated-types==0.7.0
attrs==24.2.0
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.3.2
coverage[toml]==7.6.1
exceptiongroup==1.2.2
google-ai-generativelanguage==0.6.9
google-api-core[grpc]==2.19.2
google-api-python-client==2.145.0
google-auth==2.34.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.0
googleapis-common-protos==1.65.0
grpcio==1.66.1
grpcio-status==1.66.1
httplib2==0.22.0
hypothesis==6.45.0
idna==3.8
iniconfig==2.0.0
mock==5.1.0
opentracing==2.4.0
packaging==24.1
pillow==10.4.0
pluggy==1.5.0
proto-plus==1.24.0
protobuf==5.28.0
pyasn1==0.6.0
pyasn1-modules==0.4.0
pydantic==2.9.1
pydantic-core==2.23.3
pyparsing==3.1.4
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-cov==5.0.0
pytest-mock==3.14.0
requests==2.32.3
rsa==4.9
sortedcontainers==2.4.0
tomli==2.0.1
tqdm==4.66.5
typing-extensions==4.12.2
uritemplate==4.1.1
urllib3==2.2.2
2 changes: 2 additions & 0 deletions ddtrace/_monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"elasticsearch": True,
"algoliasearch": True,
"futures": True,
"google_generativeai": True,
"gevent": True,
"graphql": True,
"grpc": True,
Expand Down Expand Up @@ -139,6 +140,7 @@
"aws_lambda": ("datadog_lambda",),
"httplib": ("http.client",),
"kafka": ("confluent_kafka",),
"google_generativeai": ("google.generativeai",),
}


Expand Down
91 changes: 91 additions & 0 deletions ddtrace/contrib/google_generativeai/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""
The Gemini integration instruments the Google Gemini Python API to traces for requests made to Google models.

All traces submitted from the Gemini integration are tagged by:

- ``service``, ``env``, ``version``: see the `Unified Service Tagging docs <https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging>`_.
- ``google_generativeai.request.model``: Google model used in the request.
- ``google_generativeai.request.api_key``: Google Gemini API key used to make the request (obfuscated to match the Google AI Studio UI representation ``...XXXX`` where ``XXXX`` is the last 4 digits of the key).


(beta) Prompt and Completion Sampling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Prompt texts and completion content for the ``generateContent`` endpoint are collected in span tags with a default sampling rate of ``1.0``.
These tags will have truncation applied if the text exceeds the configured character limit.


Enabling
~~~~~~~~

The Gemini integration is enabled automatically when you use
:ref:`ddtrace-run<ddtracerun>` or :ref:`import ddtrace.auto<ddtraceauto>`.

Alternatively, use :func:`patch() <ddtrace.patch>` to manually enable the Gemini integration::

from ddtrace import config, patch

patch(google_generativeai=True)


Global Configuration
~~~~~~~~~~~~~~~~~~~~

.. py:data:: ddtrace.config.google_generativeai["service"]

The service name reported by default for Gemini requests.

Alternatively, you can set this option with the ``DD_SERVICE`` or ``DD_GOOGLE_GENERATIVEAI_SERVICE`` environment
variables.

Default: ``DD_SERVICE``


.. py:data:: (beta) ddtrace.config.google_generativeai["span_char_limit"]

Configure the maximum number of characters for the following data within span tags:

- Text inputs and completions

Text exceeding the maximum number of characters is truncated to the character limit
and has ``...`` appended to the end.

Alternatively, you can set this option with the ``DD_GOOGLE_GENERATIVEAI_SPAN_CHAR_LIMIT`` environment
variable.

Default: ``128``


.. py:data:: (beta) ddtrace.config.google_generativeai["span_prompt_completion_sample_rate"]

Configure the sample rate for the collection of prompts and completions as span tags.

Alternatively, you can set this option with the ``DD_GOOGLE_GENERATIVEAI_SPAN_PROMPT_COMPLETION_SAMPLE_RATE`` environment
variable.

Default: ``1.0``


Instance Configuration
~~~~~~~~~~~~~~~~~~~~~~

To configure the Gemini integration on a per-instance basis use the
``Pin`` API::

import google.generativeai as genai
from ddtrace import Pin, config

Pin.override(genai, service="my-gemini-service")
""" # noqa: E501
from ddtrace.internal.utils.importlib import require_modules


required_modules = ["google.generativeai"]

with require_modules(required_modules) as missing_modules:
if not missing_modules:
from ..internal.google_generativeai.patch import get_version
from ..internal.google_generativeai.patch import patch
from ..internal.google_generativeai.patch import unpatch

__all__ = ["patch", "unpatch", "get_version"]
2 changes: 1 addition & 1 deletion ddtrace/contrib/internal/anthropic/_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from ddtrace.contrib.internal.anthropic.utils import tag_tool_use_output_on_span
from ddtrace.internal.logger import get_logger
from ddtrace.llmobs._integrations.anthropic import _get_attr
from ddtrace.llmobs._utils import _get_attr


log = get_logger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion ddtrace/contrib/internal/anthropic/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from ddtrace.internal.logger import get_logger
from ddtrace.internal.utils import get_argument_value
from ddtrace.llmobs._integrations import AnthropicIntegration
from ddtrace.llmobs._integrations.anthropic import _get_attr
from ddtrace.llmobs._utils import _get_attr
from ddtrace.pin import Pin


Expand Down
2 changes: 1 addition & 1 deletion ddtrace/contrib/internal/anthropic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Optional

from ddtrace.internal.logger import get_logger
from ddtrace.llmobs._integrations.anthropic import _get_attr
from ddtrace.llmobs._utils import _get_attr


log = get_logger(__name__)
Expand Down
Loading
Loading