sentry-sdk 2.41.0__tar.gz → 2.42.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- {sentry_sdk-2.41.0/sentry_sdk.egg-info → sentry_sdk-2.42.0}/PKG-INFO +3 -1
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/pyproject.toml +4 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/consts.py +10 -1
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/__init__.py +1 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/aiohttp.py +4 -1
- sentry_sdk-2.42.0/sentry_sdk/integrations/google_genai/__init__.py +298 -0
- sentry_sdk-2.42.0/sentry_sdk/integrations/google_genai/consts.py +16 -0
- sentry_sdk-2.42.0/sentry_sdk/integrations/google_genai/streaming.py +155 -0
- sentry_sdk-2.42.0/sentry_sdk/integrations/google_genai/utils.py +566 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/httpx.py +16 -5
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/ray.py +20 -4
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/stdlib.py +8 -1
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/tracing_utils.py +64 -24
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0/sentry_sdk.egg-info}/PKG-INFO +3 -1
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/SOURCES.txt +4 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/requires.txt +3 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/setup.py +2 -1
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/LICENSE +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/MANIFEST.in +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/README.md +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_compat.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_init_implementation.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_log_batcher.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_lru_cache.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_metrics.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_metrics_batcher.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_queue.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_types.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/_werkzeug.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/ai/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/ai/monitoring.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/ai/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/api.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/attachments.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/client.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/crons/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/crons/api.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/crons/consts.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/crons/decorator.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/debug.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/envelope.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/feature_flags.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/hub.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/_asgi_common.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/_wsgi_common.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/anthropic.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/argv.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/ariadne.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/arq.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/asgi.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/asyncio.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/asyncpg.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/atexit.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/aws_lambda.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/beam.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/boto3.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/bottle.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/celery/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/celery/beat.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/celery/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/chalice.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/clickhouse_driver.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/cloud_resource_context.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/cohere.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/dedupe.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/asgi.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/caching.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/middleware.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/signals_handlers.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/templates.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/transactions.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/django/views.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/dramatiq.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/excepthook.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/executing.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/falcon.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/fastapi.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/flask.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/gcp.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/gnu_backtrace.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/gql.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/graphene.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/aio/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/aio/client.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/aio/server.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/client.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/consts.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/grpc/server.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/huey.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/huggingface_hub.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/langchain.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/langgraph.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/launchdarkly.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/litellm.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/litestar.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/logging.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/loguru.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/modules.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/consts.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/patches/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/patches/agent_run.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/patches/models.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/patches/runner.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/patches/tools.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/ai_client.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/execute_tool.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/handoff.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openai_agents/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/openfeature.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/opentelemetry/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/opentelemetry/consts.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/opentelemetry/integration.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/opentelemetry/propagator.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/opentelemetry/span_processor.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/pure_eval.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/pymongo.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/pyramid.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/quart.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/_async_common.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/_sync_common.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/consts.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/modules/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/modules/caches.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/modules/queries.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/rb.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/redis.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/redis_cluster.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/redis/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/rq.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/rust_tracing.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/sanic.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/serverless.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/socket.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/spark/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/spark/spark_driver.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/spark/spark_worker.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/sqlalchemy.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/starlette.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/starlite.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/statsig.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/strawberry.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/sys_exit.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/threading.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/tornado.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/trytond.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/typer.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/unleash.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/unraisablehook.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/integrations/wsgi.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/logger.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/monitor.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/profiler/__init__.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/profiler/continuous_profiler.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/profiler/transaction_profiler.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/profiler/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/py.typed +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/scope.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/scrubber.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/serializer.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/session.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/sessions.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/spotlight.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/tracing.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/transport.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/types.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk/worker.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/dependency_links.txt +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/entry_points.txt +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/not-zip-safe +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/sentry_sdk.egg-info/top_level.txt +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/setup.cfg +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_ai_monitoring.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_api.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_basics.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_client.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_conftest.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_crons.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_dsc.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_envelope.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_exceptiongroup.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_feature_flags.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_full_stack_frames.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_gevent.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_import.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_logs.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_lru_cache.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_metrics.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_monitor.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_propagationcontext.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_scope.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_scrubber.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_serializer.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_sessions.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_spotlight.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_tracing_utils.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_transport.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_types.py +0 -0
- {sentry_sdk-2.41.0 → sentry_sdk-2.42.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sentry-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.42.0
|
|
4
4
|
Summary: Python client for Sentry (https://sentry.io)
|
|
5
5
|
Home-page: https://github.com/getsentry/sentry-python
|
|
6
6
|
Author: Sentry Team and Contributors
|
|
@@ -118,6 +118,8 @@ Provides-Extra: tornado
|
|
|
118
118
|
Requires-Dist: tornado>=6; extra == "tornado"
|
|
119
119
|
Provides-Extra: unleash
|
|
120
120
|
Requires-Dist: UnleashClient>=6.0.1; extra == "unleash"
|
|
121
|
+
Provides-Extra: google-genai
|
|
122
|
+
Requires-Dist: google-genai>=1.29.0; extra == "google-genai"
|
|
121
123
|
Dynamic: author
|
|
122
124
|
Dynamic: author-email
|
|
123
125
|
Dynamic: classifier
|
|
@@ -118,6 +118,10 @@ ignore_missing_imports = true
|
|
|
118
118
|
module = "langgraph.*"
|
|
119
119
|
ignore_missing_imports = true
|
|
120
120
|
|
|
121
|
+
[[tool.mypy.overrides]]
|
|
122
|
+
module = "google.genai.*"
|
|
123
|
+
ignore_missing_imports = true
|
|
124
|
+
|
|
121
125
|
[[tool.mypy.overrides]]
|
|
122
126
|
module = "executing.*"
|
|
123
127
|
ignore_missing_imports = true
|
|
@@ -909,6 +909,8 @@ class ClientConstructor:
|
|
|
909
909
|
error_sampler=None, # type: Optional[Callable[[Event, Hint], Union[float, bool]]]
|
|
910
910
|
enable_db_query_source=True, # type: bool
|
|
911
911
|
db_query_source_threshold_ms=100, # type: int
|
|
912
|
+
enable_http_request_source=False, # type: bool
|
|
913
|
+
http_request_source_threshold_ms=100, # type: int
|
|
912
914
|
spotlight=None, # type: Optional[Union[bool, str]]
|
|
913
915
|
cert_file=None, # type: Optional[str]
|
|
914
916
|
key_file=None, # type: Optional[str]
|
|
@@ -1264,6 +1266,13 @@ class ClientConstructor:
|
|
|
1264
1266
|
|
|
1265
1267
|
The query location will be added to the query for queries slower than the specified threshold.
|
|
1266
1268
|
|
|
1269
|
+
:param enable_http_request_source: When enabled, the source location will be added to outgoing HTTP requests.
|
|
1270
|
+
|
|
1271
|
+
:param http_request_source_threshold_ms: The threshold in milliseconds for adding the source location to an
|
|
1272
|
+
outgoing HTTP request.
|
|
1273
|
+
|
|
1274
|
+
The request location will be added to the request for requests slower than the specified threshold.
|
|
1275
|
+
|
|
1267
1276
|
:param custom_repr: A custom `repr <https://docs.python.org/3/library/functions.html#repr>`_ function to run
|
|
1268
1277
|
while serializing an object.
|
|
1269
1278
|
|
|
@@ -1339,4 +1348,4 @@ DEFAULT_OPTIONS = _get_default_options()
|
|
|
1339
1348
|
del _get_default_options
|
|
1340
1349
|
|
|
1341
1350
|
|
|
1342
|
-
VERSION = "2.
|
|
1351
|
+
VERSION = "2.42.0"
|
|
@@ -22,7 +22,7 @@ from sentry_sdk.tracing import (
|
|
|
22
22
|
SOURCE_FOR_STYLE,
|
|
23
23
|
TransactionSource,
|
|
24
24
|
)
|
|
25
|
-
from sentry_sdk.tracing_utils import should_propagate_trace
|
|
25
|
+
from sentry_sdk.tracing_utils import should_propagate_trace, add_http_request_source
|
|
26
26
|
from sentry_sdk.utils import (
|
|
27
27
|
capture_internal_exceptions,
|
|
28
28
|
ensure_integration_enabled,
|
|
@@ -279,6 +279,9 @@ def create_trace_config():
|
|
|
279
279
|
span.set_data("reason", params.response.reason)
|
|
280
280
|
span.finish()
|
|
281
281
|
|
|
282
|
+
with capture_internal_exceptions():
|
|
283
|
+
add_http_request_source(span)
|
|
284
|
+
|
|
282
285
|
trace_config = TraceConfig()
|
|
283
286
|
|
|
284
287
|
trace_config.on_request_start.append(on_request_start)
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
AsyncIterator,
|
|
5
|
+
Callable,
|
|
6
|
+
Iterator,
|
|
7
|
+
List,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
import sentry_sdk
|
|
11
|
+
from sentry_sdk.ai.utils import get_start_span_function
|
|
12
|
+
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
13
|
+
from sentry_sdk.consts import OP, SPANDATA
|
|
14
|
+
from sentry_sdk.tracing import SPANSTATUS
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from google.genai.models import Models, AsyncModels
|
|
19
|
+
except ImportError:
|
|
20
|
+
raise DidNotEnable("google-genai not installed")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
from .consts import IDENTIFIER, ORIGIN, GEN_AI_SYSTEM
|
|
24
|
+
from .utils import (
|
|
25
|
+
set_span_data_for_request,
|
|
26
|
+
set_span_data_for_response,
|
|
27
|
+
_capture_exception,
|
|
28
|
+
prepare_generate_content_args,
|
|
29
|
+
)
|
|
30
|
+
from .streaming import (
|
|
31
|
+
set_span_data_for_streaming_response,
|
|
32
|
+
accumulate_streaming_response,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GoogleGenAIIntegration(Integration):
|
|
37
|
+
identifier = IDENTIFIER
|
|
38
|
+
origin = ORIGIN
|
|
39
|
+
|
|
40
|
+
def __init__(self, include_prompts=True):
|
|
41
|
+
# type: (GoogleGenAIIntegration, bool) -> None
|
|
42
|
+
self.include_prompts = include_prompts
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def setup_once():
|
|
46
|
+
# type: () -> None
|
|
47
|
+
# Patch sync methods
|
|
48
|
+
Models.generate_content = _wrap_generate_content(Models.generate_content)
|
|
49
|
+
Models.generate_content_stream = _wrap_generate_content_stream(
|
|
50
|
+
Models.generate_content_stream
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Patch async methods
|
|
54
|
+
AsyncModels.generate_content = _wrap_async_generate_content(
|
|
55
|
+
AsyncModels.generate_content
|
|
56
|
+
)
|
|
57
|
+
AsyncModels.generate_content_stream = _wrap_async_generate_content_stream(
|
|
58
|
+
AsyncModels.generate_content_stream
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _wrap_generate_content_stream(f):
|
|
63
|
+
# type: (Callable[..., Any]) -> Callable[..., Any]
|
|
64
|
+
@wraps(f)
|
|
65
|
+
def new_generate_content_stream(self, *args, **kwargs):
|
|
66
|
+
# type: (Any, Any, Any) -> Any
|
|
67
|
+
integration = sentry_sdk.get_client().get_integration(GoogleGenAIIntegration)
|
|
68
|
+
if integration is None:
|
|
69
|
+
return f(self, *args, **kwargs)
|
|
70
|
+
|
|
71
|
+
_model, contents, model_name = prepare_generate_content_args(args, kwargs)
|
|
72
|
+
|
|
73
|
+
span = get_start_span_function()(
|
|
74
|
+
op=OP.GEN_AI_INVOKE_AGENT,
|
|
75
|
+
name="invoke_agent",
|
|
76
|
+
origin=ORIGIN,
|
|
77
|
+
)
|
|
78
|
+
span.__enter__()
|
|
79
|
+
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, model_name)
|
|
80
|
+
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
|
|
81
|
+
set_span_data_for_request(span, integration, model_name, contents, kwargs)
|
|
82
|
+
span.set_data(SPANDATA.GEN_AI_RESPONSE_STREAMING, True)
|
|
83
|
+
|
|
84
|
+
chat_span = sentry_sdk.start_span(
|
|
85
|
+
op=OP.GEN_AI_CHAT,
|
|
86
|
+
name=f"chat {model_name}",
|
|
87
|
+
origin=ORIGIN,
|
|
88
|
+
)
|
|
89
|
+
chat_span.__enter__()
|
|
90
|
+
chat_span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat")
|
|
91
|
+
chat_span.set_data(SPANDATA.GEN_AI_SYSTEM, GEN_AI_SYSTEM)
|
|
92
|
+
chat_span.set_data(SPANDATA.GEN_AI_REQUEST_MODEL, model_name)
|
|
93
|
+
set_span_data_for_request(chat_span, integration, model_name, contents, kwargs)
|
|
94
|
+
chat_span.set_data(SPANDATA.GEN_AI_RESPONSE_STREAMING, True)
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
stream = f(self, *args, **kwargs)
|
|
98
|
+
|
|
99
|
+
# Create wrapper iterator to accumulate responses
|
|
100
|
+
def new_iterator():
|
|
101
|
+
# type: () -> Iterator[Any]
|
|
102
|
+
chunks = [] # type: List[Any]
|
|
103
|
+
try:
|
|
104
|
+
for chunk in stream:
|
|
105
|
+
chunks.append(chunk)
|
|
106
|
+
yield chunk
|
|
107
|
+
except Exception as exc:
|
|
108
|
+
_capture_exception(exc)
|
|
109
|
+
chat_span.set_status(SPANSTATUS.ERROR)
|
|
110
|
+
raise
|
|
111
|
+
finally:
|
|
112
|
+
# Accumulate all chunks and set final response data on spans
|
|
113
|
+
if chunks:
|
|
114
|
+
accumulated_response = accumulate_streaming_response(chunks)
|
|
115
|
+
set_span_data_for_streaming_response(
|
|
116
|
+
chat_span, integration, accumulated_response
|
|
117
|
+
)
|
|
118
|
+
set_span_data_for_streaming_response(
|
|
119
|
+
span, integration, accumulated_response
|
|
120
|
+
)
|
|
121
|
+
chat_span.__exit__(None, None, None)
|
|
122
|
+
span.__exit__(None, None, None)
|
|
123
|
+
|
|
124
|
+
return new_iterator()
|
|
125
|
+
|
|
126
|
+
except Exception as exc:
|
|
127
|
+
_capture_exception(exc)
|
|
128
|
+
chat_span.__exit__(None, None, None)
|
|
129
|
+
span.__exit__(None, None, None)
|
|
130
|
+
raise
|
|
131
|
+
|
|
132
|
+
return new_generate_content_stream
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _wrap_async_generate_content_stream(f):
|
|
136
|
+
# type: (Callable[..., Any]) -> Callable[..., Any]
|
|
137
|
+
@wraps(f)
|
|
138
|
+
async def new_async_generate_content_stream(self, *args, **kwargs):
|
|
139
|
+
# type: (Any, Any, Any) -> Any
|
|
140
|
+
integration = sentry_sdk.get_client().get_integration(GoogleGenAIIntegration)
|
|
141
|
+
if integration is None:
|
|
142
|
+
return await f(self, *args, **kwargs)
|
|
143
|
+
|
|
144
|
+
_model, contents, model_name = prepare_generate_content_args(args, kwargs)
|
|
145
|
+
|
|
146
|
+
span = get_start_span_function()(
|
|
147
|
+
op=OP.GEN_AI_INVOKE_AGENT,
|
|
148
|
+
name="invoke_agent",
|
|
149
|
+
origin=ORIGIN,
|
|
150
|
+
)
|
|
151
|
+
span.__enter__()
|
|
152
|
+
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, model_name)
|
|
153
|
+
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
|
|
154
|
+
set_span_data_for_request(span, integration, model_name, contents, kwargs)
|
|
155
|
+
span.set_data(SPANDATA.GEN_AI_RESPONSE_STREAMING, True)
|
|
156
|
+
|
|
157
|
+
chat_span = sentry_sdk.start_span(
|
|
158
|
+
op=OP.GEN_AI_CHAT,
|
|
159
|
+
name=f"chat {model_name}",
|
|
160
|
+
origin=ORIGIN,
|
|
161
|
+
)
|
|
162
|
+
chat_span.__enter__()
|
|
163
|
+
chat_span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat")
|
|
164
|
+
chat_span.set_data(SPANDATA.GEN_AI_SYSTEM, GEN_AI_SYSTEM)
|
|
165
|
+
chat_span.set_data(SPANDATA.GEN_AI_REQUEST_MODEL, model_name)
|
|
166
|
+
set_span_data_for_request(chat_span, integration, model_name, contents, kwargs)
|
|
167
|
+
chat_span.set_data(SPANDATA.GEN_AI_RESPONSE_STREAMING, True)
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
stream = await f(self, *args, **kwargs)
|
|
171
|
+
|
|
172
|
+
# Create wrapper async iterator to accumulate responses
|
|
173
|
+
async def new_async_iterator():
|
|
174
|
+
# type: () -> AsyncIterator[Any]
|
|
175
|
+
chunks = [] # type: List[Any]
|
|
176
|
+
try:
|
|
177
|
+
async for chunk in stream:
|
|
178
|
+
chunks.append(chunk)
|
|
179
|
+
yield chunk
|
|
180
|
+
except Exception as exc:
|
|
181
|
+
_capture_exception(exc)
|
|
182
|
+
chat_span.set_status(SPANSTATUS.ERROR)
|
|
183
|
+
raise
|
|
184
|
+
finally:
|
|
185
|
+
# Accumulate all chunks and set final response data on spans
|
|
186
|
+
if chunks:
|
|
187
|
+
accumulated_response = accumulate_streaming_response(chunks)
|
|
188
|
+
set_span_data_for_streaming_response(
|
|
189
|
+
chat_span, integration, accumulated_response
|
|
190
|
+
)
|
|
191
|
+
set_span_data_for_streaming_response(
|
|
192
|
+
span, integration, accumulated_response
|
|
193
|
+
)
|
|
194
|
+
chat_span.__exit__(None, None, None)
|
|
195
|
+
span.__exit__(None, None, None)
|
|
196
|
+
|
|
197
|
+
return new_async_iterator()
|
|
198
|
+
|
|
199
|
+
except Exception as exc:
|
|
200
|
+
_capture_exception(exc)
|
|
201
|
+
chat_span.__exit__(None, None, None)
|
|
202
|
+
span.__exit__(None, None, None)
|
|
203
|
+
raise
|
|
204
|
+
|
|
205
|
+
return new_async_generate_content_stream
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _wrap_generate_content(f):
|
|
209
|
+
# type: (Callable[..., Any]) -> Callable[..., Any]
|
|
210
|
+
@wraps(f)
|
|
211
|
+
def new_generate_content(self, *args, **kwargs):
|
|
212
|
+
# type: (Any, Any, Any) -> Any
|
|
213
|
+
integration = sentry_sdk.get_client().get_integration(GoogleGenAIIntegration)
|
|
214
|
+
if integration is None:
|
|
215
|
+
return f(self, *args, **kwargs)
|
|
216
|
+
|
|
217
|
+
model, contents, model_name = prepare_generate_content_args(args, kwargs)
|
|
218
|
+
|
|
219
|
+
with get_start_span_function()(
|
|
220
|
+
op=OP.GEN_AI_INVOKE_AGENT,
|
|
221
|
+
name="invoke_agent",
|
|
222
|
+
origin=ORIGIN,
|
|
223
|
+
) as span:
|
|
224
|
+
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, model_name)
|
|
225
|
+
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
|
|
226
|
+
set_span_data_for_request(span, integration, model_name, contents, kwargs)
|
|
227
|
+
|
|
228
|
+
with sentry_sdk.start_span(
|
|
229
|
+
op=OP.GEN_AI_CHAT,
|
|
230
|
+
name=f"chat {model_name}",
|
|
231
|
+
origin=ORIGIN,
|
|
232
|
+
) as chat_span:
|
|
233
|
+
chat_span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat")
|
|
234
|
+
chat_span.set_data(SPANDATA.GEN_AI_SYSTEM, GEN_AI_SYSTEM)
|
|
235
|
+
chat_span.set_data(SPANDATA.GEN_AI_REQUEST_MODEL, model_name)
|
|
236
|
+
set_span_data_for_request(
|
|
237
|
+
chat_span, integration, model_name, contents, kwargs
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
response = f(self, *args, **kwargs)
|
|
242
|
+
except Exception as exc:
|
|
243
|
+
_capture_exception(exc)
|
|
244
|
+
chat_span.set_status(SPANSTATUS.ERROR)
|
|
245
|
+
raise
|
|
246
|
+
|
|
247
|
+
set_span_data_for_response(chat_span, integration, response)
|
|
248
|
+
set_span_data_for_response(span, integration, response)
|
|
249
|
+
|
|
250
|
+
return response
|
|
251
|
+
|
|
252
|
+
return new_generate_content
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def _wrap_async_generate_content(f):
|
|
256
|
+
# type: (Callable[..., Any]) -> Callable[..., Any]
|
|
257
|
+
@wraps(f)
|
|
258
|
+
async def new_async_generate_content(self, *args, **kwargs):
|
|
259
|
+
# type: (Any, Any, Any) -> Any
|
|
260
|
+
integration = sentry_sdk.get_client().get_integration(GoogleGenAIIntegration)
|
|
261
|
+
if integration is None:
|
|
262
|
+
return await f(self, *args, **kwargs)
|
|
263
|
+
|
|
264
|
+
model, contents, model_name = prepare_generate_content_args(args, kwargs)
|
|
265
|
+
|
|
266
|
+
with get_start_span_function()(
|
|
267
|
+
op=OP.GEN_AI_INVOKE_AGENT,
|
|
268
|
+
name="invoke_agent",
|
|
269
|
+
origin=ORIGIN,
|
|
270
|
+
) as span:
|
|
271
|
+
span.set_data(SPANDATA.GEN_AI_AGENT_NAME, model_name)
|
|
272
|
+
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")
|
|
273
|
+
set_span_data_for_request(span, integration, model_name, contents, kwargs)
|
|
274
|
+
|
|
275
|
+
with sentry_sdk.start_span(
|
|
276
|
+
op=OP.GEN_AI_CHAT,
|
|
277
|
+
name=f"chat {model_name}",
|
|
278
|
+
origin=ORIGIN,
|
|
279
|
+
) as chat_span:
|
|
280
|
+
chat_span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat")
|
|
281
|
+
chat_span.set_data(SPANDATA.GEN_AI_SYSTEM, GEN_AI_SYSTEM)
|
|
282
|
+
chat_span.set_data(SPANDATA.GEN_AI_REQUEST_MODEL, model_name)
|
|
283
|
+
set_span_data_for_request(
|
|
284
|
+
chat_span, integration, model_name, contents, kwargs
|
|
285
|
+
)
|
|
286
|
+
try:
|
|
287
|
+
response = await f(self, *args, **kwargs)
|
|
288
|
+
except Exception as exc:
|
|
289
|
+
_capture_exception(exc)
|
|
290
|
+
chat_span.set_status(SPANSTATUS.ERROR)
|
|
291
|
+
raise
|
|
292
|
+
|
|
293
|
+
set_span_data_for_response(chat_span, integration, response)
|
|
294
|
+
set_span_data_for_response(span, integration, response)
|
|
295
|
+
|
|
296
|
+
return response
|
|
297
|
+
|
|
298
|
+
return new_async_generate_content
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
GEN_AI_SYSTEM = "gcp.gemini"
|
|
2
|
+
|
|
3
|
+
# Mapping of tool attributes to their descriptions
|
|
4
|
+
# These are all tools that are available in the Google GenAI API
|
|
5
|
+
TOOL_ATTRIBUTES_MAP = {
|
|
6
|
+
"google_search_retrieval": "Google Search retrieval tool",
|
|
7
|
+
"google_search": "Google Search tool",
|
|
8
|
+
"retrieval": "Retrieval tool",
|
|
9
|
+
"enterprise_web_search": "Enterprise web search tool",
|
|
10
|
+
"google_maps": "Google Maps tool",
|
|
11
|
+
"code_execution": "Code execution tool",
|
|
12
|
+
"computer_use": "Computer use tool",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
IDENTIFIER = "google_genai"
|
|
16
|
+
ORIGIN = f"auto.ai.{IDENTIFIER}"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TYPE_CHECKING,
|
|
3
|
+
Any,
|
|
4
|
+
List,
|
|
5
|
+
TypedDict,
|
|
6
|
+
Optional,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from sentry_sdk.ai.utils import set_data_normalized
|
|
10
|
+
from sentry_sdk.consts import SPANDATA
|
|
11
|
+
from sentry_sdk.scope import should_send_default_pii
|
|
12
|
+
from sentry_sdk.utils import (
|
|
13
|
+
safe_serialize,
|
|
14
|
+
)
|
|
15
|
+
from .utils import (
|
|
16
|
+
extract_tool_calls,
|
|
17
|
+
extract_finish_reasons,
|
|
18
|
+
extract_contents_text,
|
|
19
|
+
extract_usage_data,
|
|
20
|
+
UsageData,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from sentry_sdk.tracing import Span
|
|
25
|
+
from google.genai.types import GenerateContentResponse
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AccumulatedResponse(TypedDict):
|
|
29
|
+
id: Optional[str]
|
|
30
|
+
model: Optional[str]
|
|
31
|
+
text: str
|
|
32
|
+
finish_reasons: List[str]
|
|
33
|
+
tool_calls: List[dict[str, Any]]
|
|
34
|
+
usage_metadata: UsageData
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def accumulate_streaming_response(chunks):
|
|
38
|
+
# type: (List[GenerateContentResponse]) -> AccumulatedResponse
|
|
39
|
+
"""Accumulate streaming chunks into a single response-like object."""
|
|
40
|
+
accumulated_text = []
|
|
41
|
+
finish_reasons = []
|
|
42
|
+
tool_calls = []
|
|
43
|
+
total_input_tokens = 0
|
|
44
|
+
total_output_tokens = 0
|
|
45
|
+
total_tokens = 0
|
|
46
|
+
total_cached_tokens = 0
|
|
47
|
+
total_reasoning_tokens = 0
|
|
48
|
+
response_id = None
|
|
49
|
+
model = None
|
|
50
|
+
|
|
51
|
+
for chunk in chunks:
|
|
52
|
+
# Extract text and tool calls
|
|
53
|
+
if getattr(chunk, "candidates", None):
|
|
54
|
+
for candidate in getattr(chunk, "candidates", []):
|
|
55
|
+
if hasattr(candidate, "content") and getattr(
|
|
56
|
+
candidate.content, "parts", []
|
|
57
|
+
):
|
|
58
|
+
extracted_text = extract_contents_text(candidate.content)
|
|
59
|
+
if extracted_text:
|
|
60
|
+
accumulated_text.append(extracted_text)
|
|
61
|
+
|
|
62
|
+
extracted_finish_reasons = extract_finish_reasons(chunk)
|
|
63
|
+
if extracted_finish_reasons:
|
|
64
|
+
finish_reasons.extend(extracted_finish_reasons)
|
|
65
|
+
|
|
66
|
+
extracted_tool_calls = extract_tool_calls(chunk)
|
|
67
|
+
if extracted_tool_calls:
|
|
68
|
+
tool_calls.extend(extracted_tool_calls)
|
|
69
|
+
|
|
70
|
+
# Accumulate token usage
|
|
71
|
+
extracted_usage_data = extract_usage_data(chunk)
|
|
72
|
+
total_input_tokens += extracted_usage_data["input_tokens"]
|
|
73
|
+
total_output_tokens += extracted_usage_data["output_tokens"]
|
|
74
|
+
total_cached_tokens += extracted_usage_data["input_tokens_cached"]
|
|
75
|
+
total_reasoning_tokens += extracted_usage_data["output_tokens_reasoning"]
|
|
76
|
+
total_tokens += extracted_usage_data["total_tokens"]
|
|
77
|
+
|
|
78
|
+
accumulated_response = AccumulatedResponse(
|
|
79
|
+
text="".join(accumulated_text),
|
|
80
|
+
finish_reasons=finish_reasons,
|
|
81
|
+
tool_calls=tool_calls,
|
|
82
|
+
usage_metadata=UsageData(
|
|
83
|
+
input_tokens=total_input_tokens,
|
|
84
|
+
output_tokens=total_output_tokens,
|
|
85
|
+
input_tokens_cached=total_cached_tokens,
|
|
86
|
+
output_tokens_reasoning=total_reasoning_tokens,
|
|
87
|
+
total_tokens=total_tokens,
|
|
88
|
+
),
|
|
89
|
+
id=response_id,
|
|
90
|
+
model=model,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return accumulated_response
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def set_span_data_for_streaming_response(span, integration, accumulated_response):
|
|
97
|
+
# type: (Span, Any, AccumulatedResponse) -> None
|
|
98
|
+
"""Set span data for accumulated streaming response."""
|
|
99
|
+
if (
|
|
100
|
+
should_send_default_pii()
|
|
101
|
+
and integration.include_prompts
|
|
102
|
+
and accumulated_response.get("text")
|
|
103
|
+
):
|
|
104
|
+
span.set_data(
|
|
105
|
+
SPANDATA.GEN_AI_RESPONSE_TEXT,
|
|
106
|
+
safe_serialize([accumulated_response["text"]]),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if accumulated_response.get("finish_reasons"):
|
|
110
|
+
set_data_normalized(
|
|
111
|
+
span,
|
|
112
|
+
SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS,
|
|
113
|
+
accumulated_response["finish_reasons"],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if accumulated_response.get("tool_calls"):
|
|
117
|
+
span.set_data(
|
|
118
|
+
SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS,
|
|
119
|
+
safe_serialize(accumulated_response["tool_calls"]),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if accumulated_response.get("id"):
|
|
123
|
+
span.set_data(SPANDATA.GEN_AI_RESPONSE_ID, accumulated_response["id"])
|
|
124
|
+
if accumulated_response.get("model"):
|
|
125
|
+
span.set_data(SPANDATA.GEN_AI_RESPONSE_MODEL, accumulated_response["model"])
|
|
126
|
+
|
|
127
|
+
if accumulated_response["usage_metadata"]["input_tokens"]:
|
|
128
|
+
span.set_data(
|
|
129
|
+
SPANDATA.GEN_AI_USAGE_INPUT_TOKENS,
|
|
130
|
+
accumulated_response["usage_metadata"]["input_tokens"],
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if accumulated_response["usage_metadata"]["input_tokens_cached"]:
|
|
134
|
+
span.set_data(
|
|
135
|
+
SPANDATA.GEN_AI_USAGE_INPUT_TOKENS_CACHED,
|
|
136
|
+
accumulated_response["usage_metadata"]["input_tokens_cached"],
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if accumulated_response["usage_metadata"]["output_tokens"]:
|
|
140
|
+
span.set_data(
|
|
141
|
+
SPANDATA.GEN_AI_USAGE_OUTPUT_TOKENS,
|
|
142
|
+
accumulated_response["usage_metadata"]["output_tokens"],
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if accumulated_response["usage_metadata"]["output_tokens_reasoning"]:
|
|
146
|
+
span.set_data(
|
|
147
|
+
SPANDATA.GEN_AI_USAGE_OUTPUT_TOKENS_REASONING,
|
|
148
|
+
accumulated_response["usage_metadata"]["output_tokens_reasoning"],
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if accumulated_response["usage_metadata"]["total_tokens"]:
|
|
152
|
+
span.set_data(
|
|
153
|
+
SPANDATA.GEN_AI_USAGE_TOTAL_TOKENS,
|
|
154
|
+
accumulated_response["usage_metadata"]["total_tokens"],
|
|
155
|
+
)
|