lmnr 0.7.1__tar.gz → 0.7.2__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.
- {lmnr-0.7.1 → lmnr-0.7.2}/PKG-INFO +48 -51
- lmnr-0.7.2/pyproject.toml +145 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py +85 -6
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/span_utils.py +57 -14
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/streaming.py +106 -6
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/pw_utils.py +0 -14
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/version.py +1 -1
- lmnr-0.7.1/pyproject.toml +0 -154
- {lmnr-0.7.1 → lmnr-0.7.2}/README.md +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/cli.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/.flake8 +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/decorators/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/litellm/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/litellm/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/config.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_emitter.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_models.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_emitter.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_models.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/span_utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/config.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_emitter.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_models.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v0/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/opentelemetry/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/attributes.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/context.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/exporter.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/instruments.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/processor.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/tracing/tracer.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/utils/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/utils/json_encoder.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/utils/package_check.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/py.typed +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/browser_use_otel.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/patchright_otel.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/playwright_otel.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/recorder/record.umd.min.cjs +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/browser/utils.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/agent.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/evaluators.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/asynchronous/resources/tags.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/agent.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/evaluators.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/resources/tags.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/datasets.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/decorators.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/eval_control.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/evaluations.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/laminar.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/log.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/types.py +0 -0
- {lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.2
|
4
4
|
Summary: Python SDK for Laminar
|
5
5
|
Author: lmnr.ai
|
6
6
|
Author-email: lmnr.ai <founders@lmnr.ai>
|
@@ -19,61 +19,59 @@ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.33.0
|
|
19
19
|
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.33.0
|
20
20
|
Requires-Dist: opentelemetry-instrumentation>=0.54b0
|
21
21
|
Requires-Dist: opentelemetry-semantic-conventions>=0.54b0
|
22
|
-
Requires-Dist: opentelemetry-semantic-conventions-ai>=0.4.
|
22
|
+
Requires-Dist: opentelemetry-semantic-conventions-ai>=0.4.11
|
23
23
|
Requires-Dist: tqdm>=4.0
|
24
24
|
Requires-Dist: tenacity>=8.0
|
25
25
|
Requires-Dist: grpcio>=1
|
26
26
|
Requires-Dist: httpx>=0.25.0
|
27
27
|
Requires-Dist: orjson>=3.10.18
|
28
28
|
Requires-Dist: packaging>=22.0
|
29
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.
|
30
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.
|
31
|
-
Requires-Dist: opentelemetry-instrumentation-bedrock>=0.
|
32
|
-
Requires-Dist: opentelemetry-instrumentation-chromadb>=0.
|
33
|
-
Requires-Dist: opentelemetry-instrumentation-cohere>=0.
|
34
|
-
Requires-Dist: opentelemetry-instrumentation-crewai>=0.
|
35
|
-
Requires-Dist: opentelemetry-instrumentation-
|
36
|
-
Requires-Dist: opentelemetry-instrumentation-
|
37
|
-
Requires-Dist: opentelemetry-instrumentation-
|
38
|
-
Requires-Dist: opentelemetry-instrumentation-
|
39
|
-
Requires-Dist: opentelemetry-instrumentation-
|
40
|
-
Requires-Dist: opentelemetry-instrumentation-
|
41
|
-
Requires-Dist: opentelemetry-instrumentation-
|
42
|
-
Requires-Dist: opentelemetry-instrumentation-
|
43
|
-
Requires-Dist: opentelemetry-instrumentation-
|
44
|
-
Requires-Dist: opentelemetry-instrumentation-
|
45
|
-
Requires-Dist: opentelemetry-instrumentation-
|
46
|
-
Requires-Dist: opentelemetry-instrumentation-
|
47
|
-
Requires-Dist: opentelemetry-instrumentation-
|
48
|
-
Requires-Dist: opentelemetry-instrumentation-
|
49
|
-
Requires-Dist: opentelemetry-instrumentation-
|
50
|
-
Requires-Dist: opentelemetry-instrumentation-
|
51
|
-
Requires-Dist: opentelemetry-instrumentation-
|
52
|
-
Requires-Dist: opentelemetry-instrumentation-
|
53
|
-
Requires-Dist: opentelemetry-instrumentation-
|
54
|
-
Requires-Dist: opentelemetry-instrumentation-
|
55
|
-
Requires-Dist: opentelemetry-instrumentation-
|
56
|
-
Requires-Dist: opentelemetry-instrumentation-
|
57
|
-
Requires-Dist: opentelemetry-instrumentation-
|
58
|
-
Requires-Dist: opentelemetry-instrumentation-
|
59
|
-
Requires-Dist: opentelemetry-instrumentation-
|
60
|
-
Requires-Dist: opentelemetry-instrumentation-
|
61
|
-
Requires-Dist: opentelemetry-instrumentation-
|
62
|
-
Requires-Dist: opentelemetry-instrumentation-
|
63
|
-
Requires-Dist: opentelemetry-instrumentation-
|
64
|
-
Requires-Dist: opentelemetry-instrumentation-
|
65
|
-
Requires-Dist: opentelemetry-instrumentation-
|
66
|
-
Requires-Dist: opentelemetry-instrumentation-
|
67
|
-
Requires-Dist: opentelemetry-instrumentation-
|
68
|
-
Requires-Dist: opentelemetry-instrumentation-
|
69
|
-
Requires-Dist: opentelemetry-instrumentation-
|
70
|
-
Requires-Dist: opentelemetry-instrumentation-
|
71
|
-
Requires-Dist: opentelemetry-instrumentation-
|
72
|
-
Requires-Dist: opentelemetry-instrumentation-
|
73
|
-
Requires-Dist: opentelemetry-instrumentation-
|
74
|
-
Requires-Dist: opentelemetry-instrumentation-
|
75
|
-
Requires-Dist: opentelemetry-instrumentation-watsonx>=0.40.12 ; extra == 'watsonx'
|
76
|
-
Requires-Dist: opentelemetry-instrumentation-weaviate>=0.40.12 ; extra == 'weaviate'
|
29
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.44.0 ; extra == 'alephalpha'
|
30
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.44.0 ; extra == 'all'
|
31
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock>=0.44.0 ; extra == 'all'
|
32
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb>=0.44.0 ; extra == 'all'
|
33
|
+
Requires-Dist: opentelemetry-instrumentation-cohere>=0.44.0 ; extra == 'all'
|
34
|
+
Requires-Dist: opentelemetry-instrumentation-crewai>=0.44.0 ; extra == 'all'
|
35
|
+
Requires-Dist: opentelemetry-instrumentation-haystack>=0.44.0 ; extra == 'all'
|
36
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb>=0.44.0 ; extra == 'all'
|
37
|
+
Requires-Dist: opentelemetry-instrumentation-langchain>=0.44.0 ; extra == 'all'
|
38
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex>=0.44.0 ; extra == 'all'
|
39
|
+
Requires-Dist: opentelemetry-instrumentation-marqo>=0.44.0 ; extra == 'all'
|
40
|
+
Requires-Dist: opentelemetry-instrumentation-mcp>=0.44.0 ; extra == 'all'
|
41
|
+
Requires-Dist: opentelemetry-instrumentation-milvus>=0.44.0 ; extra == 'all'
|
42
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai>=0.44.0 ; extra == 'all'
|
43
|
+
Requires-Dist: opentelemetry-instrumentation-ollama>=0.44.0 ; extra == 'all'
|
44
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone>=0.44.0 ; extra == 'all'
|
45
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant>=0.44.0 ; extra == 'all'
|
46
|
+
Requires-Dist: opentelemetry-instrumentation-replicate>=0.44.0 ; extra == 'all'
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-sagemaker>=0.44.0 ; extra == 'all'
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-together>=0.44.0 ; extra == 'all'
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-transformers>=0.44.0 ; extra == 'all'
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai>=0.44.0 ; extra == 'all'
|
51
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx>=0.44.0 ; extra == 'all'
|
52
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate>=0.44.0 ; extra == 'all'
|
53
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock>=0.44.0 ; extra == 'bedrock'
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb>=0.44.0 ; extra == 'chromadb'
|
55
|
+
Requires-Dist: opentelemetry-instrumentation-cohere>=0.44.0 ; extra == 'cohere'
|
56
|
+
Requires-Dist: opentelemetry-instrumentation-crewai>=0.44.0 ; extra == 'crewai'
|
57
|
+
Requires-Dist: opentelemetry-instrumentation-haystack>=0.44.0 ; extra == 'haystack'
|
58
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb>=0.44.0 ; extra == 'lancedb'
|
59
|
+
Requires-Dist: opentelemetry-instrumentation-langchain>=0.44.0 ; extra == 'langchain'
|
60
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex>=0.44.0 ; extra == 'llamaindex'
|
61
|
+
Requires-Dist: opentelemetry-instrumentation-marqo>=0.44.0 ; extra == 'marqo'
|
62
|
+
Requires-Dist: opentelemetry-instrumentation-mcp>=0.44.0 ; extra == 'mcp'
|
63
|
+
Requires-Dist: opentelemetry-instrumentation-milvus>=0.44.0 ; extra == 'milvus'
|
64
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai>=0.44.0 ; extra == 'mistralai'
|
65
|
+
Requires-Dist: opentelemetry-instrumentation-ollama>=0.44.0 ; extra == 'ollama'
|
66
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone>=0.44.0 ; extra == 'pinecone'
|
67
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant>=0.44.0 ; extra == 'qdrant'
|
68
|
+
Requires-Dist: opentelemetry-instrumentation-replicate>=0.44.0 ; extra == 'replicate'
|
69
|
+
Requires-Dist: opentelemetry-instrumentation-sagemaker>=0.44.0 ; extra == 'sagemaker'
|
70
|
+
Requires-Dist: opentelemetry-instrumentation-together>=0.44.0 ; extra == 'together'
|
71
|
+
Requires-Dist: opentelemetry-instrumentation-transformers>=0.44.0 ; extra == 'transformers'
|
72
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai>=0.44.0 ; extra == 'vertexai'
|
73
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx>=0.44.0 ; extra == 'watsonx'
|
74
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate>=0.44.0 ; extra == 'weaviate'
|
77
75
|
Requires-Python: >=3.10, <4
|
78
76
|
Provides-Extra: alephalpha
|
79
77
|
Provides-Extra: all
|
@@ -81,7 +79,6 @@ Provides-Extra: bedrock
|
|
81
79
|
Provides-Extra: chromadb
|
82
80
|
Provides-Extra: cohere
|
83
81
|
Provides-Extra: crewai
|
84
|
-
Provides-Extra: google-generativeai
|
85
82
|
Provides-Extra: haystack
|
86
83
|
Provides-Extra: lancedb
|
87
84
|
Provides-Extra: langchain
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Laminar Python
|
2
|
+
|
3
|
+
# If you are looking for information about possible extras installations,
|
4
|
+
# i.e. what you can pass into `pip install 'lmnr[extra1,extra2]'`, please see the
|
5
|
+
# `[project.optional-dependencies]` section below.
|
6
|
+
|
7
|
+
[project]
|
8
|
+
name = "lmnr"
|
9
|
+
version = "0.7.2"
|
10
|
+
description = "Python SDK for Laminar"
|
11
|
+
authors = [
|
12
|
+
{ name = "lmnr.ai", email = "founders@lmnr.ai" }
|
13
|
+
]
|
14
|
+
readme = "README.md"
|
15
|
+
requires-python = ">=3.10,<4"
|
16
|
+
license = "Apache-2.0"
|
17
|
+
dependencies = [
|
18
|
+
"pydantic (>=2.0.3,<3.0.0)",
|
19
|
+
"python-dotenv (>=1.0)",
|
20
|
+
"opentelemetry-api (>=1.33.0)",
|
21
|
+
"opentelemetry-sdk (>=1.33.0)",
|
22
|
+
"opentelemetry-exporter-otlp-proto-http (>=1.33.0)",
|
23
|
+
"opentelemetry-exporter-otlp-proto-grpc (>=1.33.0)",
|
24
|
+
"opentelemetry-instrumentation (>=0.54b0)",
|
25
|
+
"opentelemetry-semantic-conventions (>=0.54b0)",
|
26
|
+
"opentelemetry-semantic-conventions-ai (>=0.4.11)",
|
27
|
+
"tqdm (>=4.0)",
|
28
|
+
"tenacity (>=8.0)",
|
29
|
+
# Since 1.68.0, grpcio writes a warning message
|
30
|
+
# that looks scary, but is harmless.
|
31
|
+
# WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
|
32
|
+
# E0000 00:00:1737439981.199902 9456033 init.cc:229] grpc_wait_for_shutdown_with_timeout() timed out.
|
33
|
+
#
|
34
|
+
# Remove this comment when we make sure that grpcio has resolved this.
|
35
|
+
# Related issue:
|
36
|
+
# https://discuss.ai.google.dev/t/warning-all-log-messages-before-absl-initializelog-is-called-are-written-to-stderr-e0000-001731955515-629532-17124-init-cc-229-grpc-wait-for-shutdown-with-timeout-timed-out/50020
|
37
|
+
# https://github.com/grpc/grpc/issues/38490
|
38
|
+
"grpcio>=1",
|
39
|
+
"httpx>=0.25.0",
|
40
|
+
"orjson>=3.10.18",
|
41
|
+
"packaging>=22.0",
|
42
|
+
]
|
43
|
+
# poetry would auto-generate these based on requires-python, but other build
|
44
|
+
# systems don't, so we need to specify them manually.
|
45
|
+
classifiers = [
|
46
|
+
"License :: OSI Approved :: Apache Software License",
|
47
|
+
"Programming Language :: Python :: 3",
|
48
|
+
"Programming Language :: Python :: 3.10",
|
49
|
+
"Programming Language :: Python :: 3.11",
|
50
|
+
"Programming Language :: Python :: 3.12",
|
51
|
+
"Programming Language :: Python :: 3.13",
|
52
|
+
]
|
53
|
+
|
54
|
+
[project.scripts]
|
55
|
+
lmnr = "lmnr.cli:cli"
|
56
|
+
|
57
|
+
[project.optional-dependencies]
|
58
|
+
# List of all possible extras. You can specify one or more of these extras
|
59
|
+
# when installing the package, using any of the following examples:
|
60
|
+
# `pip install 'lmnr[anthropic,groq]'`
|
61
|
+
# `uv pip install 'lmnr[anthropic,groq]'`
|
62
|
+
# `uv add lmnr --extra anthropic --extra groq`
|
63
|
+
# `poetry add 'lmnr[anthropic,groq]'`
|
64
|
+
|
65
|
+
alephalpha=["opentelemetry-instrumentation-alephalpha>=0.44.0"]
|
66
|
+
bedrock=["opentelemetry-instrumentation-bedrock>=0.44.0"]
|
67
|
+
chromadb=["opentelemetry-instrumentation-chromadb>=0.44.0"]
|
68
|
+
cohere=["opentelemetry-instrumentation-cohere>=0.44.0"]
|
69
|
+
crewai=["opentelemetry-instrumentation-crewai>=0.44.0"]
|
70
|
+
haystack=["opentelemetry-instrumentation-haystack>=0.44.0"]
|
71
|
+
lancedb=["opentelemetry-instrumentation-lancedb>=0.44.0"]
|
72
|
+
langchain=["opentelemetry-instrumentation-langchain>=0.44.0"]
|
73
|
+
llamaindex=["opentelemetry-instrumentation-llamaindex>=0.44.0"]
|
74
|
+
marqo=["opentelemetry-instrumentation-marqo>=0.44.0"]
|
75
|
+
mcp=["opentelemetry-instrumentation-mcp>=0.44.0"]
|
76
|
+
milvus=["opentelemetry-instrumentation-milvus>=0.44.0"]
|
77
|
+
mistralai=["opentelemetry-instrumentation-mistralai>=0.44.0"]
|
78
|
+
ollama=["opentelemetry-instrumentation-ollama>=0.44.0"]
|
79
|
+
pinecone=["opentelemetry-instrumentation-pinecone>=0.44.0"]
|
80
|
+
qdrant=["opentelemetry-instrumentation-qdrant>=0.44.0"]
|
81
|
+
replicate=["opentelemetry-instrumentation-replicate>=0.44.0"]
|
82
|
+
sagemaker=["opentelemetry-instrumentation-sagemaker>=0.44.0"]
|
83
|
+
together=["opentelemetry-instrumentation-together>=0.44.0"]
|
84
|
+
transformers=["opentelemetry-instrumentation-transformers>=0.44.0"]
|
85
|
+
vertexai=["opentelemetry-instrumentation-vertexai>=0.44.0"]
|
86
|
+
watsonx=["opentelemetry-instrumentation-watsonx>=0.44.0"]
|
87
|
+
weaviate=["opentelemetry-instrumentation-weaviate>=0.44.0"]
|
88
|
+
# `all` is the group added for convenience, if you want to install all
|
89
|
+
# the instrumentations.
|
90
|
+
# we suggest using package-manager-specific commands instead,
|
91
|
+
# like `uv add lmnr --all-extras`
|
92
|
+
all = [
|
93
|
+
"opentelemetry-instrumentation-alephalpha>=0.44.0",
|
94
|
+
"opentelemetry-instrumentation-bedrock>=0.44.0",
|
95
|
+
"opentelemetry-instrumentation-chromadb>=0.44.0",
|
96
|
+
"opentelemetry-instrumentation-cohere>=0.44.0",
|
97
|
+
"opentelemetry-instrumentation-crewai>=0.44.0",
|
98
|
+
"opentelemetry-instrumentation-haystack>=0.44.0",
|
99
|
+
"opentelemetry-instrumentation-lancedb>=0.44.0",
|
100
|
+
"opentelemetry-instrumentation-langchain>=0.44.0",
|
101
|
+
"opentelemetry-instrumentation-llamaindex>=0.44.0",
|
102
|
+
"opentelemetry-instrumentation-marqo>=0.44.0",
|
103
|
+
"opentelemetry-instrumentation-mcp>=0.44.0",
|
104
|
+
"opentelemetry-instrumentation-milvus>=0.44.0",
|
105
|
+
"opentelemetry-instrumentation-mistralai>=0.44.0",
|
106
|
+
"opentelemetry-instrumentation-ollama>=0.44.0",
|
107
|
+
"opentelemetry-instrumentation-pinecone>=0.44.0",
|
108
|
+
"opentelemetry-instrumentation-qdrant>=0.44.0",
|
109
|
+
"opentelemetry-instrumentation-replicate>=0.44.0",
|
110
|
+
"opentelemetry-instrumentation-sagemaker>=0.44.0",
|
111
|
+
"opentelemetry-instrumentation-together>=0.44.0",
|
112
|
+
"opentelemetry-instrumentation-transformers>=0.44.0",
|
113
|
+
"opentelemetry-instrumentation-vertexai>=0.44.0",
|
114
|
+
"opentelemetry-instrumentation-watsonx>=0.44.0",
|
115
|
+
"opentelemetry-instrumentation-weaviate>=0.44.0"
|
116
|
+
]
|
117
|
+
|
118
|
+
[dependency-groups]
|
119
|
+
dev = [
|
120
|
+
"autopep8>=2.3.2",
|
121
|
+
"flake8>=7.2.0",
|
122
|
+
"pytest>=8.3.5",
|
123
|
+
"pytest-sugar>=1.0.0",
|
124
|
+
"pytest-asyncio>=0.26.0",
|
125
|
+
"playwright>=1.52.0",
|
126
|
+
"vcrpy>=7.0.0",
|
127
|
+
"openai>=1.98.0",
|
128
|
+
"pytest-recording>=0.13.4",
|
129
|
+
"patchright>=1.52.3",
|
130
|
+
"google-genai>=1.19.0",
|
131
|
+
"langgraph>=0.4.8",
|
132
|
+
"langchain-core>=0.3.64",
|
133
|
+
"langchain>=0.3.25",
|
134
|
+
"litellm>=1.72.6",
|
135
|
+
"groq>=0.30.0",
|
136
|
+
"anthropic>=0.60.0",
|
137
|
+
"langchain-openai>=0.3.28",
|
138
|
+
]
|
139
|
+
|
140
|
+
[build-system]
|
141
|
+
requires = ["uv_build>=0.7.21,<0.8"]
|
142
|
+
build-backend = "uv_build"
|
143
|
+
|
144
|
+
[tool.uv.workspace]
|
145
|
+
members = ["examples/fastapi-app"]
|
@@ -29,6 +29,10 @@ from .utils import (
|
|
29
29
|
shared_metrics_attributes,
|
30
30
|
should_emit_events,
|
31
31
|
)
|
32
|
+
from .streaming import (
|
33
|
+
WrappedAsyncMessageStreamManager,
|
34
|
+
WrappedMessageStreamManager,
|
35
|
+
)
|
32
36
|
from .version import __version__
|
33
37
|
|
34
38
|
from lmnr.opentelemetry_lib.tracing.context import get_current_context
|
@@ -52,6 +56,7 @@ logger = logging.getLogger(__name__)
|
|
52
56
|
|
53
57
|
_instruments = ("anthropic >= 0.3.11",)
|
54
58
|
|
59
|
+
|
55
60
|
WRAPPED_METHODS = [
|
56
61
|
{
|
57
62
|
"package": "anthropic.resources.completions",
|
@@ -71,6 +76,15 @@ WRAPPED_METHODS = [
|
|
71
76
|
"method": "stream",
|
72
77
|
"span_name": "anthropic.chat",
|
73
78
|
},
|
79
|
+
# This method is on an async resource, but is meant to be called as
|
80
|
+
# an async context manager (async with), which we don't need to await;
|
81
|
+
# thus, we wrap it with a sync wrapper
|
82
|
+
{
|
83
|
+
"package": "anthropic.resources.messages",
|
84
|
+
"object": "AsyncMessages",
|
85
|
+
"method": "stream",
|
86
|
+
"span_name": "anthropic.chat",
|
87
|
+
},
|
74
88
|
]
|
75
89
|
|
76
90
|
WRAPPED_AMETHODS = [
|
@@ -86,12 +100,6 @@ WRAPPED_AMETHODS = [
|
|
86
100
|
"method": "create",
|
87
101
|
"span_name": "anthropic.chat",
|
88
102
|
},
|
89
|
-
{
|
90
|
-
"package": "anthropic.resources.messages",
|
91
|
-
"object": "AsyncMessages",
|
92
|
-
"method": "stream",
|
93
|
-
"span_name": "anthropic.chat",
|
94
|
-
},
|
95
103
|
]
|
96
104
|
|
97
105
|
|
@@ -99,6 +107,23 @@ def is_streaming_response(response):
|
|
99
107
|
return isinstance(response, Stream) or isinstance(response, AsyncStream)
|
100
108
|
|
101
109
|
|
110
|
+
def is_stream_manager(response):
|
111
|
+
"""Check if response is a MessageStreamManager or AsyncMessageStreamManager"""
|
112
|
+
try:
|
113
|
+
from anthropic.lib.streaming._messages import (
|
114
|
+
MessageStreamManager,
|
115
|
+
AsyncMessageStreamManager,
|
116
|
+
)
|
117
|
+
|
118
|
+
return isinstance(response, (MessageStreamManager, AsyncMessageStreamManager))
|
119
|
+
except ImportError:
|
120
|
+
# Check by class name as fallback
|
121
|
+
return (
|
122
|
+
response.__class__.__name__ == "MessageStreamManager"
|
123
|
+
or response.__class__.__name__ == "AsyncMessageStreamManager"
|
124
|
+
)
|
125
|
+
|
126
|
+
|
102
127
|
@dont_throw
|
103
128
|
async def _aset_token_usage(
|
104
129
|
span,
|
@@ -437,6 +462,33 @@ def _wrap(
|
|
437
462
|
event_logger,
|
438
463
|
kwargs,
|
439
464
|
)
|
465
|
+
elif is_stream_manager(response):
|
466
|
+
if response.__class__.__name__ == "AsyncMessageStreamManager":
|
467
|
+
return WrappedAsyncMessageStreamManager(
|
468
|
+
response,
|
469
|
+
span,
|
470
|
+
instance._client,
|
471
|
+
start_time,
|
472
|
+
token_histogram,
|
473
|
+
choice_counter,
|
474
|
+
duration_histogram,
|
475
|
+
exception_counter,
|
476
|
+
event_logger,
|
477
|
+
kwargs,
|
478
|
+
)
|
479
|
+
else:
|
480
|
+
return WrappedMessageStreamManager(
|
481
|
+
response,
|
482
|
+
span,
|
483
|
+
instance._client,
|
484
|
+
start_time,
|
485
|
+
token_histogram,
|
486
|
+
choice_counter,
|
487
|
+
duration_histogram,
|
488
|
+
exception_counter,
|
489
|
+
event_logger,
|
490
|
+
kwargs,
|
491
|
+
)
|
440
492
|
elif response:
|
441
493
|
try:
|
442
494
|
metric_attributes = shared_metrics_attributes(response)
|
@@ -532,6 +584,33 @@ async def _awrap(
|
|
532
584
|
event_logger,
|
533
585
|
kwargs,
|
534
586
|
)
|
587
|
+
elif is_stream_manager(response):
|
588
|
+
if response.__class__.__name__ == "AsyncMessageStreamManager":
|
589
|
+
return WrappedAsyncMessageStreamManager(
|
590
|
+
response,
|
591
|
+
span,
|
592
|
+
instance._client,
|
593
|
+
start_time,
|
594
|
+
token_histogram,
|
595
|
+
choice_counter,
|
596
|
+
duration_histogram,
|
597
|
+
exception_counter,
|
598
|
+
event_logger,
|
599
|
+
kwargs,
|
600
|
+
)
|
601
|
+
else:
|
602
|
+
return WrappedMessageStreamManager(
|
603
|
+
response,
|
604
|
+
span,
|
605
|
+
instance._client,
|
606
|
+
start_time,
|
607
|
+
token_histogram,
|
608
|
+
choice_counter,
|
609
|
+
duration_histogram,
|
610
|
+
exception_counter,
|
611
|
+
event_logger,
|
612
|
+
kwargs,
|
613
|
+
)
|
535
614
|
elif response:
|
536
615
|
metric_attributes = shared_metrics_attributes(response)
|
537
616
|
|
@@ -113,18 +113,43 @@ async def aset_input_attributes(span, kwargs):
|
|
113
113
|
)
|
114
114
|
for i, message in enumerate(kwargs.get("messages")):
|
115
115
|
prompt_index = i + (1 if has_system_message else 0)
|
116
|
+
content = message.get("content")
|
117
|
+
tool_use_blocks = []
|
118
|
+
other_blocks = []
|
119
|
+
if isinstance(content, list):
|
120
|
+
for block in content:
|
121
|
+
if dict(block).get("type") == "tool_use":
|
122
|
+
tool_use_blocks.append(dict(block))
|
123
|
+
else:
|
124
|
+
other_blocks.append(block)
|
125
|
+
content = other_blocks
|
116
126
|
set_span_attribute(
|
117
127
|
span,
|
118
128
|
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content",
|
119
|
-
await _dump_content(
|
120
|
-
message_index=i, span=span, content=message.get("content")
|
121
|
-
),
|
129
|
+
await _dump_content(message_index=i, span=span, content=content),
|
122
130
|
)
|
123
131
|
set_span_attribute(
|
124
132
|
span,
|
125
133
|
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role",
|
126
134
|
message.get("role"),
|
127
135
|
)
|
136
|
+
if tool_use_blocks:
|
137
|
+
for tool_num, tool_use_block in enumerate(tool_use_blocks):
|
138
|
+
set_span_attribute(
|
139
|
+
span,
|
140
|
+
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.tool_calls.{tool_num}.id",
|
141
|
+
tool_use_block.get("id"),
|
142
|
+
)
|
143
|
+
set_span_attribute(
|
144
|
+
span,
|
145
|
+
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.tool_calls.{tool_num}.name",
|
146
|
+
tool_use_block.get("name"),
|
147
|
+
)
|
148
|
+
set_span_attribute(
|
149
|
+
span,
|
150
|
+
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.tool_calls.{tool_num}.arguments",
|
151
|
+
json.dumps(tool_use_block.get("input")),
|
152
|
+
)
|
128
153
|
|
129
154
|
if kwargs.get("tools") is not None:
|
130
155
|
for i, tool in enumerate(kwargs.get("tools")):
|
@@ -160,8 +185,8 @@ def _set_span_completions(span, response):
|
|
160
185
|
content_block_type = content.type
|
161
186
|
# usually, Antrhopic responds with just one text block,
|
162
187
|
# but the API allows for multiple text blocks, so concatenate them
|
163
|
-
if content_block_type == "text":
|
164
|
-
text += content.text
|
188
|
+
if content_block_type == "text" and hasattr(content, "text"):
|
189
|
+
text += content.text or ""
|
165
190
|
elif content_block_type == "thinking":
|
166
191
|
content = dict(content)
|
167
192
|
# override the role to thinking
|
@@ -242,15 +267,33 @@ def set_streaming_response_attributes(span, complete_response_events):
|
|
242
267
|
if not span.is_recording() or not complete_response_events:
|
243
268
|
return
|
244
269
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
270
|
+
index = 0
|
271
|
+
for event in complete_response_events:
|
272
|
+
prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}"
|
273
|
+
set_span_attribute(span, f"{prefix}.finish_reason", event.get("finish_reason"))
|
274
|
+
role = "thinking" if event.get("type") == "thinking" else "assistant"
|
275
|
+
# Thinking is added as a separate completion, so we need to increment the index
|
276
|
+
if event.get("type") == "thinking":
|
277
|
+
index += 1
|
278
|
+
set_span_attribute(span, f"{prefix}.role", role)
|
279
|
+
if event.get("type") == "tool_use":
|
280
|
+
set_span_attribute(
|
281
|
+
span,
|
282
|
+
f"{prefix}.tool_calls.0.id",
|
283
|
+
event.get("id"),
|
284
|
+
)
|
249
285
|
set_span_attribute(
|
250
|
-
span,
|
286
|
+
span,
|
287
|
+
f"{prefix}.tool_calls.0.name",
|
288
|
+
event.get("name"),
|
251
289
|
)
|
252
|
-
|
253
|
-
|
290
|
+
tool_arguments = event.get("input")
|
291
|
+
if tool_arguments is not None:
|
292
|
+
set_span_attribute(
|
293
|
+
span,
|
294
|
+
f"{prefix}.tool_calls.0.arguments",
|
295
|
+
# already stringified
|
296
|
+
tool_arguments,
|
297
|
+
)
|
298
|
+
else:
|
254
299
|
set_span_attribute(span, f"{prefix}.content", event.get("text"))
|
255
|
-
except Exception as e:
|
256
|
-
logger.warning("Failed to set completion attributes, error: %s", str(e))
|
@@ -40,15 +40,19 @@ def _process_response_item(item, complete_response):
|
|
40
40
|
complete_response["events"].append(
|
41
41
|
{"index": index, "text": "", "type": item.content_block.type}
|
42
42
|
)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
if item.content_block.type == "tool_use":
|
44
|
+
complete_response["events"][index]["id"] = item.content_block.id
|
45
|
+
complete_response["events"][index]["name"] = item.content_block.name
|
46
|
+
complete_response["events"][index]["input"] = ""
|
47
|
+
|
48
|
+
elif item.type == "content_block_delta":
|
47
49
|
index = item.index
|
48
50
|
if item.delta.type == "thinking_delta":
|
49
|
-
complete_response["events"][index]["text"] += item.delta.thinking
|
51
|
+
complete_response["events"][index]["text"] += item.delta.thinking or ""
|
50
52
|
elif item.delta.type == "text_delta":
|
51
|
-
complete_response["events"][index]["text"] += item.delta.text
|
53
|
+
complete_response["events"][index]["text"] += item.delta.text or ""
|
54
|
+
elif item.delta.type == "input_json_delta":
|
55
|
+
complete_response["events"][index]["input"] += item.delta.partial_json
|
52
56
|
elif item.type == "message_delta":
|
53
57
|
for event in complete_response.get("events", []):
|
54
58
|
event["finish_reason"] = item.delta.stop_reason
|
@@ -293,3 +297,99 @@ async def abuild_from_streaming_response(
|
|
293
297
|
if span.is_recording():
|
294
298
|
span.set_status(Status(StatusCode.OK))
|
295
299
|
span.end()
|
300
|
+
|
301
|
+
|
302
|
+
class WrappedMessageStreamManager:
|
303
|
+
"""Wrapper for MessageStreamManager that handles instrumentation"""
|
304
|
+
|
305
|
+
def __init__(
|
306
|
+
self,
|
307
|
+
stream_manager,
|
308
|
+
span,
|
309
|
+
instance,
|
310
|
+
start_time,
|
311
|
+
token_histogram,
|
312
|
+
choice_counter,
|
313
|
+
duration_histogram,
|
314
|
+
exception_counter,
|
315
|
+
event_logger,
|
316
|
+
kwargs,
|
317
|
+
):
|
318
|
+
self._stream_manager = stream_manager
|
319
|
+
self._span = span
|
320
|
+
self._instance = instance
|
321
|
+
self._start_time = start_time
|
322
|
+
self._token_histogram = token_histogram
|
323
|
+
self._choice_counter = choice_counter
|
324
|
+
self._duration_histogram = duration_histogram
|
325
|
+
self._exception_counter = exception_counter
|
326
|
+
self._event_logger = event_logger
|
327
|
+
self._kwargs = kwargs
|
328
|
+
|
329
|
+
def __enter__(self):
|
330
|
+
# Call the original stream manager's __enter__ to get the actual stream
|
331
|
+
stream = self._stream_manager.__enter__()
|
332
|
+
# Return the wrapped stream
|
333
|
+
return build_from_streaming_response(
|
334
|
+
self._span,
|
335
|
+
stream,
|
336
|
+
self._instance,
|
337
|
+
self._start_time,
|
338
|
+
self._token_histogram,
|
339
|
+
self._choice_counter,
|
340
|
+
self._duration_histogram,
|
341
|
+
self._exception_counter,
|
342
|
+
self._event_logger,
|
343
|
+
self._kwargs,
|
344
|
+
)
|
345
|
+
|
346
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
347
|
+
return self._stream_manager.__exit__(exc_type, exc_val, exc_tb)
|
348
|
+
|
349
|
+
|
350
|
+
class WrappedAsyncMessageStreamManager:
|
351
|
+
"""Wrapper for AsyncMessageStreamManager that handles instrumentation"""
|
352
|
+
|
353
|
+
def __init__(
|
354
|
+
self,
|
355
|
+
stream_manager,
|
356
|
+
span,
|
357
|
+
instance,
|
358
|
+
start_time,
|
359
|
+
token_histogram,
|
360
|
+
choice_counter,
|
361
|
+
duration_histogram,
|
362
|
+
exception_counter,
|
363
|
+
event_logger,
|
364
|
+
kwargs,
|
365
|
+
):
|
366
|
+
self._stream_manager = stream_manager
|
367
|
+
self._span = span
|
368
|
+
self._instance = instance
|
369
|
+
self._start_time = start_time
|
370
|
+
self._token_histogram = token_histogram
|
371
|
+
self._choice_counter = choice_counter
|
372
|
+
self._duration_histogram = duration_histogram
|
373
|
+
self._exception_counter = exception_counter
|
374
|
+
self._event_logger = event_logger
|
375
|
+
self._kwargs = kwargs
|
376
|
+
|
377
|
+
async def __aenter__(self):
|
378
|
+
# Call the original stream manager's __aenter__ to get the actual stream
|
379
|
+
stream = await self._stream_manager.__aenter__()
|
380
|
+
# Return the wrapped stream
|
381
|
+
return abuild_from_streaming_response(
|
382
|
+
self._span,
|
383
|
+
stream,
|
384
|
+
self._instance,
|
385
|
+
self._start_time,
|
386
|
+
self._token_histogram,
|
387
|
+
self._choice_counter,
|
388
|
+
self._duration_histogram,
|
389
|
+
self._exception_counter,
|
390
|
+
self._event_logger,
|
391
|
+
self._kwargs,
|
392
|
+
)
|
393
|
+
|
394
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
395
|
+
return await self._stream_manager.__aexit__(exc_type, exc_val, exc_tb)
|
@@ -487,12 +487,6 @@ def start_recording_events_sync(page: SyncPage, session_id: str, client: Laminar
|
|
487
487
|
trace_id = format(span.get_span_context().trace_id, "032x")
|
488
488
|
span.set_attribute("lmnr.internal.has_browser_session", True)
|
489
489
|
|
490
|
-
try:
|
491
|
-
if page.evaluate("""() => typeof window.lmnrSendEvents !== 'undefined'"""):
|
492
|
-
return
|
493
|
-
except Exception:
|
494
|
-
pass
|
495
|
-
|
496
490
|
def send_events_from_browser(events):
|
497
491
|
try:
|
498
492
|
if events and len(events) > 0:
|
@@ -524,14 +518,6 @@ async def start_recording_events_async(
|
|
524
518
|
span = trace.get_current_span(ctx)
|
525
519
|
trace_id = format(span.get_span_context().trace_id, "032x")
|
526
520
|
span.set_attribute("lmnr.internal.has_browser_session", True)
|
527
|
-
|
528
|
-
try:
|
529
|
-
if await page.evaluate(
|
530
|
-
"""() => typeof window.lmnrSendEvents !== 'undefined'"""
|
531
|
-
):
|
532
|
-
return
|
533
|
-
except Exception:
|
534
|
-
pass
|
535
521
|
|
536
522
|
async def send_events_from_browser(events):
|
537
523
|
try:
|
lmnr-0.7.1/pyproject.toml
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
# Laminar Python
|
2
|
-
|
3
|
-
# If you are looking for information about possible extras installations,
|
4
|
-
# i.e. what you can pass into `pip install 'lmnr[extra1,extra2]'`, please see the
|
5
|
-
# `[project.optional-dependencies]` section below.
|
6
|
-
|
7
|
-
[project]
|
8
|
-
name = "lmnr"
|
9
|
-
version = "0.7.1"
|
10
|
-
description = "Python SDK for Laminar"
|
11
|
-
authors = [
|
12
|
-
{ name = "lmnr.ai", email = "founders@lmnr.ai" }
|
13
|
-
]
|
14
|
-
readme = "README.md"
|
15
|
-
requires-python = ">=3.10,<4"
|
16
|
-
license = "Apache-2.0"
|
17
|
-
dependencies = [
|
18
|
-
"pydantic (>=2.0.3,<3.0.0)",
|
19
|
-
"python-dotenv (>=1.0)",
|
20
|
-
"opentelemetry-api (>=1.33.0)",
|
21
|
-
"opentelemetry-sdk (>=1.33.0)",
|
22
|
-
"opentelemetry-exporter-otlp-proto-http (>=1.33.0)",
|
23
|
-
"opentelemetry-exporter-otlp-proto-grpc (>=1.33.0)",
|
24
|
-
"opentelemetry-instrumentation (>=0.54b0)",
|
25
|
-
"opentelemetry-semantic-conventions (>=0.54b0)",
|
26
|
-
"opentelemetry-semantic-conventions-ai (>=0.4.9)",
|
27
|
-
"tqdm (>=4.0)",
|
28
|
-
"tenacity (>=8.0)",
|
29
|
-
# Since 1.68.0, grpcio writes a warning message
|
30
|
-
# that looks scary, but is harmless.
|
31
|
-
# WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
|
32
|
-
# E0000 00:00:1737439981.199902 9456033 init.cc:229] grpc_wait_for_shutdown_with_timeout() timed out.
|
33
|
-
#
|
34
|
-
# Remove this comment when we make sure that grpcio has resolved this.
|
35
|
-
# Related issue:
|
36
|
-
# https://discuss.ai.google.dev/t/warning-all-log-messages-before-absl-initializelog-is-called-are-written-to-stderr-e0000-001731955515-629532-17124-init-cc-229-grpc-wait-for-shutdown-with-timeout-timed-out/50020
|
37
|
-
# https://github.com/grpc/grpc/issues/38490
|
38
|
-
"grpcio>=1",
|
39
|
-
"httpx>=0.25.0",
|
40
|
-
"orjson>=3.10.18",
|
41
|
-
"packaging>=22.0",
|
42
|
-
]
|
43
|
-
# poetry would auto-generate these based on requires-python, but other build
|
44
|
-
# systems don't, so we need to specify them manually.
|
45
|
-
classifiers = [
|
46
|
-
"License :: OSI Approved :: Apache Software License",
|
47
|
-
"Programming Language :: Python :: 3",
|
48
|
-
"Programming Language :: Python :: 3.10",
|
49
|
-
"Programming Language :: Python :: 3.11",
|
50
|
-
"Programming Language :: Python :: 3.12",
|
51
|
-
"Programming Language :: Python :: 3.13",
|
52
|
-
]
|
53
|
-
|
54
|
-
[project.scripts]
|
55
|
-
lmnr = "lmnr.cli:cli"
|
56
|
-
|
57
|
-
[project.optional-dependencies]
|
58
|
-
# List of all possible extras. You can specify one or more of these extras
|
59
|
-
# when installing the package, using any of the following examples:
|
60
|
-
# `pip install 'lmnr[anthropic,groq]'`
|
61
|
-
# `uv pip install 'lmnr[anthropic,groq]'`
|
62
|
-
# `uv add lmnr --extra anthropic --extra groq`
|
63
|
-
# `poetry add 'lmnr[anthropic,groq]'`
|
64
|
-
|
65
|
-
alephalpha=["opentelemetry-instrumentation-alephalpha>=0.40.12"]
|
66
|
-
bedrock=["opentelemetry-instrumentation-bedrock>=0.40.12"]
|
67
|
-
chromadb=["opentelemetry-instrumentation-chromadb>=0.40.12"]
|
68
|
-
cohere=["opentelemetry-instrumentation-cohere>=0.40.12"]
|
69
|
-
crewai=["opentelemetry-instrumentation-crewai>=0.40.12"]
|
70
|
-
# Newer versions of the instrumentation library try to wrap both
|
71
|
-
# google-generativeai and google-genai. The latter seems not very
|
72
|
-
# thoroughly tested. We have our own instrumentation of the latter; the
|
73
|
-
# former is on deprecation path, so we pin it to the latest version not
|
74
|
-
# wrapping google-genai.
|
75
|
-
# https://github.com/traceloop/openllmetry/pull/3014
|
76
|
-
google-generativeai=["opentelemetry-instrumentation-google-generativeai<0.40.10"]
|
77
|
-
haystack=["opentelemetry-instrumentation-haystack>=0.40.12"]
|
78
|
-
lancedb=["opentelemetry-instrumentation-lancedb>=0.40.12"]
|
79
|
-
langchain=["opentelemetry-instrumentation-langchain>=0.40.12"]
|
80
|
-
llamaindex=["opentelemetry-instrumentation-llamaindex>=0.40.12"]
|
81
|
-
marqo=["opentelemetry-instrumentation-marqo>=0.40.12"]
|
82
|
-
mcp=["opentelemetry-instrumentation-mcp>=0.40.12"]
|
83
|
-
milvus=["opentelemetry-instrumentation-milvus>=0.40.12"]
|
84
|
-
mistralai=["opentelemetry-instrumentation-mistralai>=0.40.12"]
|
85
|
-
ollama=["opentelemetry-instrumentation-ollama>=0.40.12"]
|
86
|
-
pinecone=["opentelemetry-instrumentation-pinecone>=0.40.12"]
|
87
|
-
qdrant=["opentelemetry-instrumentation-qdrant>=0.40.12"]
|
88
|
-
replicate=["opentelemetry-instrumentation-replicate>=0.40.12"]
|
89
|
-
sagemaker=["opentelemetry-instrumentation-sagemaker>=0.40.12"]
|
90
|
-
together=["opentelemetry-instrumentation-together>=0.40.12"]
|
91
|
-
transformers=["opentelemetry-instrumentation-transformers>=0.40.12"]
|
92
|
-
vertexai=["opentelemetry-instrumentation-vertexai>=0.40.12"]
|
93
|
-
watsonx=["opentelemetry-instrumentation-watsonx>=0.40.12"]
|
94
|
-
weaviate=["opentelemetry-instrumentation-weaviate>=0.40.12"]
|
95
|
-
# `all` is the group added for convenience, if you want to install all
|
96
|
-
# the instrumentations.
|
97
|
-
# we suggest using package-manager-specific commands instead,
|
98
|
-
# like `uv add lmnr --all-extras`
|
99
|
-
all = [
|
100
|
-
"opentelemetry-instrumentation-alephalpha>=0.40.12",
|
101
|
-
"opentelemetry-instrumentation-bedrock>=0.40.12",
|
102
|
-
"opentelemetry-instrumentation-chromadb>=0.40.12",
|
103
|
-
"opentelemetry-instrumentation-cohere>=0.40.12",
|
104
|
-
"opentelemetry-instrumentation-crewai>=0.40.12",
|
105
|
-
# See comment above on the google-generativeai extra.
|
106
|
-
"opentelemetry-instrumentation-google-generativeai<0.40.10",
|
107
|
-
"opentelemetry-instrumentation-haystack>=0.40.12",
|
108
|
-
"opentelemetry-instrumentation-lancedb>=0.40.12",
|
109
|
-
"opentelemetry-instrumentation-langchain>=0.40.12",
|
110
|
-
"opentelemetry-instrumentation-llamaindex>=0.40.12",
|
111
|
-
"opentelemetry-instrumentation-marqo>=0.40.12",
|
112
|
-
"opentelemetry-instrumentation-mcp>=0.40.12",
|
113
|
-
"opentelemetry-instrumentation-milvus>=0.40.12",
|
114
|
-
"opentelemetry-instrumentation-mistralai>=0.40.12",
|
115
|
-
"opentelemetry-instrumentation-ollama>=0.40.12",
|
116
|
-
"opentelemetry-instrumentation-pinecone>=0.40.12",
|
117
|
-
"opentelemetry-instrumentation-qdrant>=0.40.12",
|
118
|
-
"opentelemetry-instrumentation-replicate>=0.40.12",
|
119
|
-
"opentelemetry-instrumentation-sagemaker>=0.40.12",
|
120
|
-
"opentelemetry-instrumentation-together>=0.40.12",
|
121
|
-
"opentelemetry-instrumentation-transformers>=0.40.12",
|
122
|
-
"opentelemetry-instrumentation-vertexai>=0.40.12",
|
123
|
-
"opentelemetry-instrumentation-watsonx>=0.40.12",
|
124
|
-
"opentelemetry-instrumentation-weaviate>=0.40.12"
|
125
|
-
]
|
126
|
-
|
127
|
-
[dependency-groups]
|
128
|
-
dev = [
|
129
|
-
"autopep8>=2.3.2",
|
130
|
-
"flake8>=7.2.0",
|
131
|
-
"pytest>=8.3.5",
|
132
|
-
"pytest-sugar>=1.0.0",
|
133
|
-
"pytest-asyncio>=0.26.0",
|
134
|
-
"playwright>=1.52.0",
|
135
|
-
"vcrpy>=7.0.0",
|
136
|
-
"openai>=1.98.0",
|
137
|
-
"pytest-recording>=0.13.4",
|
138
|
-
"patchright>=1.52.3",
|
139
|
-
"google-genai>=1.19.0",
|
140
|
-
"langgraph>=0.4.8",
|
141
|
-
"langchain-core>=0.3.64",
|
142
|
-
"langchain>=0.3.25",
|
143
|
-
"litellm>=1.72.6",
|
144
|
-
"groq>=0.30.0",
|
145
|
-
"anthropic>=0.57.1",
|
146
|
-
"langchain-openai>=0.3.28",
|
147
|
-
]
|
148
|
-
|
149
|
-
[build-system]
|
150
|
-
requires = ["uv_build>=0.7.21,<0.8"]
|
151
|
-
build-backend = "uv_build"
|
152
|
-
|
153
|
-
[tool.uv.workspace]
|
154
|
-
members = ["examples/fastapi-app"]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py
RENAMED
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py
RENAMED
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{lmnr-0.7.1 → lmnr-0.7.2}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|