openlit 1.10.0__tar.gz → 1.13.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.
Files changed (53) hide show
  1. {openlit-1.10.0 → openlit-1.13.0}/PKG-INFO +18 -15
  2. {openlit-1.10.0 → openlit-1.13.0}/README.md +17 -14
  3. {openlit-1.10.0 → openlit-1.13.0}/pyproject.toml +1 -1
  4. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/__init__.py +220 -32
  5. openlit-1.13.0/src/openlit/instrumentation/gpt4all/__init__.py +52 -0
  6. openlit-1.13.0/src/openlit/instrumentation/gpt4all/gpt4all.py +352 -0
  7. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/async_groq.py +1 -1
  8. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/groq.py +1 -1
  9. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/async_azure_openai.py +2 -2
  10. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/async_openai.py +1 -1
  11. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/azure_openai.py +2 -2
  12. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/openai.py +1 -1
  13. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/transformers/transformers.py +1 -1
  14. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/semcov/__init__.py +4 -3
  15. {openlit-1.10.0 → openlit-1.13.0}/LICENSE +0 -0
  16. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/__helpers.py +0 -0
  17. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/__init__.py +0 -0
  18. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/anthropic.py +0 -0
  19. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/async_anthropic.py +0 -0
  20. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/bedrock/__init__.py +0 -0
  21. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/bedrock/bedrock.py +0 -0
  22. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/chroma/__init__.py +0 -0
  23. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/chroma/chroma.py +0 -0
  24. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/cohere/__init__.py +0 -0
  25. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/cohere/cohere.py +0 -0
  26. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/embedchain/__init__.py +0 -0
  27. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/embedchain/embedchain.py +0 -0
  28. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/__init__.py +0 -0
  29. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/haystack/__init__.py +0 -0
  30. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/haystack/haystack.py +0 -0
  31. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/langchain/__init__.py +0 -0
  32. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/langchain/langchain.py +0 -0
  33. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/llamaindex/__init__.py +0 -0
  34. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/llamaindex/llamaindex.py +0 -0
  35. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/milvus/__init__.py +0 -0
  36. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/milvus/milvus.py +0 -0
  37. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/__init__.py +0 -0
  38. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/async_mistral.py +0 -0
  39. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/mistral.py +0 -0
  40. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/__init__.py +0 -0
  41. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/async_ollama.py +0 -0
  42. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/ollama.py +0 -0
  43. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/__init__.py +0 -0
  44. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/pinecone/__init__.py +0 -0
  45. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/pinecone/pinecone.py +0 -0
  46. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/qdrant/__init__.py +0 -0
  47. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/qdrant/qdrant.py +0 -0
  48. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/transformers/__init__.py +0 -0
  49. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/__init__.py +0 -0
  50. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/async_vertexai.py +0 -0
  51. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/vertexai.py +0 -0
  52. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/otel/metrics.py +0 -0
  53. {openlit-1.10.0 → openlit-1.13.0}/src/openlit/otel/tracing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openlit
3
- Version: 1.10.0
3
+ Version: 1.13.0
4
4
  Summary: OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications, facilitating the integration of observability into your GenAI-driven projects
5
5
  Home-page: https://github.com/openlit/openlit/tree/main/openlit/python
6
6
  Keywords: OpenTelemetry,otel,otlp,llm,tracing,openai,anthropic,claude,cohere,llm monitoring,observability,monitoring,gpt,Generative AI,chatGPT
@@ -36,7 +36,8 @@ OpenTelemetry Auto-Instrumentation for GenAI & LLM Applications</h1>
36
36
  [![GitHub Contributors](https://img.shields.io/github/contributors/openlit/openlit)](https://github.com/openlit/openlit/graphs/contributors)
37
37
 
38
38
  [![Slack](https://img.shields.io/badge/Slack-4A154B?logo=slack&logoColor=white)](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
39
- [![X](https://img.shields.io/badge/follow-%40OpenLIT-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
39
+ [![Discord](https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white)](https://discord.gg/rjvTm6zd)
40
+ [![X](https://img.shields.io/badge/follow-%40openlit__io-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
40
41
 
41
42
  ![OpenLIT Connections Banner](https://github.com/openlit/.github/blob/main/profile/assets/github-readme-connections-banner.png?raw=true)
42
43
 
@@ -51,26 +52,28 @@ This project adheres to the [Semantic Conventions](https://github.com/open-telem
51
52
 
52
53
  ## Auto Instrumentation Capabilities
53
54
 
54
- | LLMs | Vector DBs | Frameworks |
55
- |----------------------------------------------------------|----------------------------------------------|----------------------------------------------|
56
- | [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
57
- | [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
58
- | [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
59
- | [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
60
- | [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
61
- | [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
55
+ | LLMs | Vector DBs | Frameworks |
56
+ |-----------------------------------------------------------------|----------------------------------------------|----------------------------------------------|
57
+ | [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
58
+ | [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
59
+ | [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
60
+ | [✅ GPT4All](https://docs.openlit.io/latest/integrations/gpt4all) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
61
+ | [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | | [✅ EmbedChain](https://docs.openlit.io/latest/integrations/embedchain) |
62
+ | [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
63
+ | [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
62
64
  | [✅ HuggingFace Transformers](https://docs.openlit.io/latest/integrations/huggingface) | |
63
- | [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
65
+ | [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
64
66
  | [✅ Vertex AI](https://docs.openlit.io/latest/integrations/vertexai) | |
65
- | [✅ Groq](https://docs.openlit.io/latest/integrations/groq) | |
67
+ | [✅ Groq](https://docs.openlit.io/latest/integrations/groq) |
66
68
 
67
69
  ## Supported Destinations
68
70
  - [✅ OpenTelemetry Collector](https://docs.openlit.io/latest/connections/otelcol)
69
71
  - [✅ Prometheus + Tempo](https://docs.openlit.io/latest/connections/prometheus-tempo)
70
72
  - [✅ Prometheus + Jaeger](https://docs.openlit.io/latest/connections/prometheus-jaeger)
71
73
  - [✅ Grafana Cloud](https://docs.openlit.io/latest/connections/grafanacloud)
72
- - [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
73
74
  - [✅ New Relic](https://docs.openlit.io/latest/connections/new-relic)
75
+ - [✅ Elastic](https://docs.openlit.io/latest/connections/elastic)
76
+ - [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
74
77
  - [✅ SigNoz](https://docs.openlit.io/latest/connections/signoz)
75
78
  - [✅ Dynatrace](https://docs.openlit.io/latest/connections/dynatrace)
76
79
  - [✅ OpenObserve](https://docs.openlit.io/latest/connections/openobserve)
@@ -189,7 +192,7 @@ Whether it's big or small, we love contributions 💚. Check out our [Contributi
189
192
 
190
193
  Unsure where to start? Here are a few ways to get involved:
191
194
 
192
- - Join our [Slack channel](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
195
+ - Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
193
196
 
194
197
  Your input helps us grow and improve, and we're here to support you every step of the way.
195
198
 
@@ -198,7 +201,7 @@ Your input helps us grow and improve, and we're here to support you every step o
198
201
  Connect with the OpenLIT community and maintainers for support, discussions, and updates:
199
202
 
200
203
  - 🌟 If you like it, Leave a star on our [GitHub](https://github.com/openlit/openlit/)
201
- - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) Community for live interactions and questions.
204
+ - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community for live interactions and questions.
202
205
  - 🐞 Report bugs on our [GitHub Issues](https://github.com/openlit/openlit/issues) to help us improve OpenLIT.
203
206
  - 𝕏 Follow us on [X](https://x.com/openlit_io) for the latest updates and news.
204
207
 
@@ -11,7 +11,8 @@ OpenTelemetry Auto-Instrumentation for GenAI & LLM Applications</h1>
11
11
  [![GitHub Contributors](https://img.shields.io/github/contributors/openlit/openlit)](https://github.com/openlit/openlit/graphs/contributors)
12
12
 
13
13
  [![Slack](https://img.shields.io/badge/Slack-4A154B?logo=slack&logoColor=white)](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
14
- [![X](https://img.shields.io/badge/follow-%40OpenLIT-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
14
+ [![Discord](https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white)](https://discord.gg/rjvTm6zd)
15
+ [![X](https://img.shields.io/badge/follow-%40openlit__io-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
15
16
 
16
17
  ![OpenLIT Connections Banner](https://github.com/openlit/.github/blob/main/profile/assets/github-readme-connections-banner.png?raw=true)
17
18
 
@@ -26,26 +27,28 @@ This project adheres to the [Semantic Conventions](https://github.com/open-telem
26
27
 
27
28
  ## Auto Instrumentation Capabilities
28
29
 
29
- | LLMs | Vector DBs | Frameworks |
30
- |----------------------------------------------------------|----------------------------------------------|----------------------------------------------|
31
- | [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
32
- | [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
33
- | [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
34
- | [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
35
- | [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
36
- | [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
30
+ | LLMs | Vector DBs | Frameworks |
31
+ |-----------------------------------------------------------------|----------------------------------------------|----------------------------------------------|
32
+ | [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
33
+ | [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
34
+ | [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
35
+ | [✅ GPT4All](https://docs.openlit.io/latest/integrations/gpt4all) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
36
+ | [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | | [✅ EmbedChain](https://docs.openlit.io/latest/integrations/embedchain) |
37
+ | [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
38
+ | [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
37
39
  | [✅ HuggingFace Transformers](https://docs.openlit.io/latest/integrations/huggingface) | |
38
- | [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
40
+ | [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
39
41
  | [✅ Vertex AI](https://docs.openlit.io/latest/integrations/vertexai) | |
40
- | [✅ Groq](https://docs.openlit.io/latest/integrations/groq) | |
42
+ | [✅ Groq](https://docs.openlit.io/latest/integrations/groq) |
41
43
 
42
44
  ## Supported Destinations
43
45
  - [✅ OpenTelemetry Collector](https://docs.openlit.io/latest/connections/otelcol)
44
46
  - [✅ Prometheus + Tempo](https://docs.openlit.io/latest/connections/prometheus-tempo)
45
47
  - [✅ Prometheus + Jaeger](https://docs.openlit.io/latest/connections/prometheus-jaeger)
46
48
  - [✅ Grafana Cloud](https://docs.openlit.io/latest/connections/grafanacloud)
47
- - [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
48
49
  - [✅ New Relic](https://docs.openlit.io/latest/connections/new-relic)
50
+ - [✅ Elastic](https://docs.openlit.io/latest/connections/elastic)
51
+ - [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
49
52
  - [✅ SigNoz](https://docs.openlit.io/latest/connections/signoz)
50
53
  - [✅ Dynatrace](https://docs.openlit.io/latest/connections/dynatrace)
51
54
  - [✅ OpenObserve](https://docs.openlit.io/latest/connections/openobserve)
@@ -164,7 +167,7 @@ Whether it's big or small, we love contributions 💚. Check out our [Contributi
164
167
 
165
168
  Unsure where to start? Here are a few ways to get involved:
166
169
 
167
- - Join our [Slack channel](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
170
+ - Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
168
171
 
169
172
  Your input helps us grow and improve, and we're here to support you every step of the way.
170
173
 
@@ -173,6 +176,6 @@ Your input helps us grow and improve, and we're here to support you every step o
173
176
  Connect with the OpenLIT community and maintainers for support, discussions, and updates:
174
177
 
175
178
  - 🌟 If you like it, Leave a star on our [GitHub](https://github.com/openlit/openlit/)
176
- - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) Community for live interactions and questions.
179
+ - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community for live interactions and questions.
177
180
  - 🐞 Report bugs on our [GitHub Issues](https://github.com/openlit/openlit/issues) to help us improve OpenLIT.
178
181
  - 𝕏 Follow us on [X](https://x.com/openlit_io) for the latest updates and news.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openlit"
3
- version = "1.10.0"
3
+ version = "1.13.0"
4
4
  description = "OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications, facilitating the integration of observability into your GenAI-driven projects"
5
5
  authors = ["OpenLIT"]
6
6
  repository = "https://github.com/openlit/openlit/tree/main/openlit/python"
@@ -1,17 +1,26 @@
1
+ # pylint: disable=broad-exception-caught
1
2
  """
2
3
  The __init__.py module for the openLIT package.
3
4
  This module sets up the openLIT configuration and instrumentation for various
4
5
  large language models (LLMs).
5
6
  """
7
+
6
8
  from typing import Dict
7
9
  import logging
8
10
  from importlib.util import find_spec
11
+ from functools import wraps
12
+ from contextlib import contextmanager
13
+
9
14
 
10
15
  # Import internal modules for setting up tracing and fetching pricing info.
16
+ from opentelemetry import trace as t
17
+ from opentelemetry.trace import SpanKind, Status, StatusCode, Span
18
+ from openlit.semcov import SemanticConvetion
11
19
  from openlit.otel.tracing import setup_tracing
12
20
  from openlit.otel.metrics import setup_meter
13
21
  from openlit.__helpers import fetch_pricing_info
14
22
 
23
+
15
24
  # Instrumentors for various large language models.
16
25
  from openlit.instrumentation.openai import OpenAIInstrumentor
17
26
  from openlit.instrumentation.anthropic import AnthropicInstrumentor
@@ -21,6 +30,7 @@ from openlit.instrumentation.bedrock import BedrockInstrumentor
21
30
  from openlit.instrumentation.vertexai import VertexAIInstrumentor
22
31
  from openlit.instrumentation.groq import GroqInstrumentor
23
32
  from openlit.instrumentation.ollama import OllamaInstrumentor
33
+ from openlit.instrumentation.gpt4all import GPT4AllInstrumentor
24
34
  from openlit.instrumentation.langchain import LangChainInstrumentor
25
35
  from openlit.instrumentation.llamaindex import LlamaIndexInstrumentor
26
36
  from openlit.instrumentation.haystack import HaystackInstrumentor
@@ -34,13 +44,14 @@ from openlit.instrumentation.transformers import TransformersInstrumentor
34
44
  # Set up logging for error and information messages.
35
45
  logger = logging.getLogger(__name__)
36
46
 
47
+
37
48
  class OpenlitConfig:
38
49
  """
39
50
  A Singleton Configuration class for openLIT.
40
-
51
+
41
52
  This class maintains a single instance of configuration settings including
42
53
  environment details, application name, and tracing information throughout the openLIT package.
43
-
54
+
44
55
  Attributes:
45
56
  environment (str): Deployment environment of the application.
46
57
  application_name (str): Name of the application using openLIT.
@@ -51,6 +62,7 @@ class OpenlitConfig:
51
62
  disable_batch (bool): Flag to disable batch span processing in tracing.
52
63
  trace_content (bool): Flag to enable or disable tracing of content.
53
64
  """
65
+
54
66
  _instance = None
55
67
 
56
68
  def __new__(cls):
@@ -75,9 +87,19 @@ class OpenlitConfig:
75
87
  cls.disable_metrics = False
76
88
 
77
89
  @classmethod
78
- def update_config(cls, environment, application_name, tracer, otlp_endpoint,
79
- otlp_headers, disable_batch, trace_content, metrics_dict,
80
- disable_metrics, pricing_json):
90
+ def update_config(
91
+ cls,
92
+ environment,
93
+ application_name,
94
+ tracer,
95
+ otlp_endpoint,
96
+ otlp_headers,
97
+ disable_batch,
98
+ trace_content,
99
+ metrics_dict,
100
+ disable_metrics,
101
+ pricing_json,
102
+ ):
81
103
  """
82
104
  Updates the configuration based on provided parameters.
83
105
 
@@ -103,8 +125,14 @@ class OpenlitConfig:
103
125
  cls.trace_content = trace_content
104
126
  cls.disable_metrics = disable_metrics
105
127
 
106
- def instrument_if_available(instrumentor_name, instrumentor_instance, config,
107
- disabled_instrumentors, module_name_map):
128
+
129
+ def instrument_if_available(
130
+ instrumentor_name,
131
+ instrumentor_instance,
132
+ config,
133
+ disabled_instrumentors,
134
+ module_name_map,
135
+ ):
108
136
  """Instruments the specified instrumentor if its library is available."""
109
137
  if instrumentor_name in disabled_instrumentors:
110
138
  return
@@ -120,22 +148,33 @@ def instrument_if_available(instrumentor_name, instrumentor_instance, config,
120
148
  pricing_info=config.pricing_info,
121
149
  trace_content=config.trace_content,
122
150
  metrics_dict=config.metrics_dict,
123
- disable_metrics=config.disable_metrics
151
+ disable_metrics=config.disable_metrics,
124
152
  )
125
153
 
126
154
  # pylint: disable=broad-exception-caught
127
155
  except Exception as e:
128
156
  logger.error("Failed to instrument %s: %s", instrumentor_name, e)
129
157
 
130
- def init(environment="default", application_name="default", tracer=None, otlp_endpoint=None,
131
- otlp_headers=None, disable_batch=False, trace_content=True, disabled_instrumentors=None,
132
- meter=None, disable_metrics=False, pricing_json=None):
158
+
159
+ def init(
160
+ environment="default",
161
+ application_name="default",
162
+ tracer=None,
163
+ otlp_endpoint=None,
164
+ otlp_headers=None,
165
+ disable_batch=False,
166
+ trace_content=True,
167
+ disabled_instrumentors=None,
168
+ meter=None,
169
+ disable_metrics=False,
170
+ pricing_json=None,
171
+ ):
133
172
  """
134
173
  Initializes the openLIT configuration and setups tracing.
135
-
136
- This function sets up the openLIT environment with provided configurations
174
+
175
+ This function sets up the openLIT environment with provided configurations
137
176
  and initializes instrumentors for tracing.
138
-
177
+
139
178
  Args:
140
179
  environment (str): Deployment environment.
141
180
  application_name (str): Application name.
@@ -154,13 +193,14 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
154
193
 
155
194
  module_name_map = {
156
195
  "openai": "openai",
157
- "anthropic": "anthropic",
158
- "cohere": "cohere",
196
+ "anthropic": "anthropic",
197
+ "cohere": "cohere",
159
198
  "mistral": "mistralai",
160
199
  "bedrock": "boto3",
161
200
  "vertexai": "vertexai",
162
201
  "groq": "groq",
163
202
  "ollama": "ollama",
203
+ "gpt4all": "gpt4all",
164
204
  "langchain": "langchain",
165
205
  "llama_index": "llama_index",
166
206
  "haystack": "haystack",
@@ -169,12 +209,16 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
169
209
  "pinecone": "pinecone",
170
210
  "qdrant": "qdrant_client",
171
211
  "milvus": "pymilvus",
172
- "transformers": "transformers"
212
+ "transformers": "transformers",
173
213
  }
174
214
 
175
- invalid_instrumentors = [name for name in disabled_instrumentors if name not in module_name_map]
215
+ invalid_instrumentors = [
216
+ name for name in disabled_instrumentors if name not in module_name_map
217
+ ]
176
218
  for invalid_name in invalid_instrumentors:
177
- logger.warning("Invalid instrumentor name detected and ignored: '%s'", invalid_name)
219
+ logger.warning(
220
+ "Invalid instrumentor name detected and ignored: '%s'", invalid_name
221
+ )
178
222
 
179
223
  try:
180
224
  # Retrieve or create the single configuration instance.
@@ -183,9 +227,11 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
183
227
  # Setup tracing based on the provided or default configuration.
184
228
  tracer = setup_tracing(
185
229
  application_name=application_name,
186
- environment=environment, tracer=tracer,
187
- otlp_endpoint=otlp_endpoint, otlp_headers=otlp_headers,
188
- disable_batch=disable_batch
230
+ environment=environment,
231
+ tracer=tracer,
232
+ otlp_endpoint=otlp_endpoint,
233
+ otlp_headers=otlp_headers,
234
+ disable_batch=disable_batch,
189
235
  )
190
236
 
191
237
  if not tracer:
@@ -193,18 +239,31 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
193
239
  return
194
240
 
195
241
  # Setup meter and receive metrics_dict instead of meter
196
- metrics_dict = setup_meter(application_name=application_name,
197
- environment=environment, meter=meter,
198
- otlp_endpoint=otlp_endpoint, otlp_headers=otlp_headers)
242
+ metrics_dict = setup_meter(
243
+ application_name=application_name,
244
+ environment=environment,
245
+ meter=meter,
246
+ otlp_endpoint=otlp_endpoint,
247
+ otlp_headers=otlp_headers,
248
+ )
199
249
 
200
250
  if not metrics_dict:
201
251
  logger.error("openLIT metrics setup failed. Metrics will not be available.")
202
252
  return
203
253
 
204
254
  # Update global configuration with the provided settings.
205
- config.update_config(environment, application_name, tracer, otlp_endpoint,
206
- otlp_headers, disable_batch, trace_content,
207
- metrics_dict, disable_metrics, pricing_json)
255
+ config.update_config(
256
+ environment,
257
+ application_name,
258
+ tracer,
259
+ otlp_endpoint,
260
+ otlp_headers,
261
+ disable_batch,
262
+ trace_content,
263
+ metrics_dict,
264
+ disable_metrics,
265
+ pricing_json,
266
+ )
208
267
 
209
268
  # Map instrumentor names to their instances
210
269
  instrumentor_instances = {
@@ -216,6 +275,7 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
216
275
  "vertexai": VertexAIInstrumentor(),
217
276
  "groq": GroqInstrumentor(),
218
277
  "ollama": OllamaInstrumentor(),
278
+ "gpt4all": GPT4AllInstrumentor(),
219
279
  "langchain": LangChainInstrumentor(),
220
280
  "llama_index": LlamaIndexInstrumentor(),
221
281
  "haystack": HaystackInstrumentor(),
@@ -224,14 +284,142 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
224
284
  "pinecone": PineconeInstrumentor(),
225
285
  "qdrant": QdrantInstrumentor(),
226
286
  "milvus": MilvusInstrumentor(),
227
- "transformers": TransformersInstrumentor()
287
+ "transformers": TransformersInstrumentor(),
228
288
  }
229
289
 
230
290
  # Initialize and instrument only the enabled instrumentors
231
291
  for name, instrumentor in instrumentor_instances.items():
232
- instrument_if_available(name, instrumentor, config,
233
- disabled_instrumentors, module_name_map)
292
+ instrument_if_available(
293
+ name, instrumentor, config, disabled_instrumentors, module_name_map
294
+ )
234
295
 
235
- # pylint: disable=broad-exception-caught
236
296
  except Exception as e:
237
297
  logger.error("Error during openLIT initialization: %s", e)
298
+
299
+
300
+ def trace(wrapped):
301
+ """
302
+ Generates a telemetry wrapper for messages to collect metrics.
303
+ """
304
+
305
+ @wraps(wrapped)
306
+ def wrapper(*args, **kwargs):
307
+ __trace = t.get_tracer_provider()
308
+ with __trace.get_tracer(__name__).start_as_current_span(
309
+ name=wrapped.__name__,
310
+ kind=SpanKind.CLIENT,
311
+ ) as span:
312
+ try:
313
+ response = wrapped(*args, **kwargs)
314
+ span.set_attribute(
315
+ SemanticConvetion.GEN_AI_CONTENT_COMPLETION, response
316
+ )
317
+ span.set_status(Status(StatusCode.OK))
318
+
319
+ except Exception as e:
320
+ response = None
321
+ span.record_exception(e)
322
+ span.set_status(status=Status(StatusCode.ERROR), description=e)
323
+ logging.error("Error in %s: %s", wrapped.__name__, e, exc_info=True)
324
+
325
+ # Adding function arguments as metadata
326
+ try:
327
+ span.set_attribute("function.args", str(args))
328
+ span.set_attribute("function.kwargs", str(kwargs))
329
+ span.set_attribute(
330
+ SemanticConvetion.GEN_AI_APPLICATION_NAME,
331
+ OpenlitConfig.application_name,
332
+ )
333
+ span.set_attribute(
334
+ SemanticConvetion.GEN_AI_ENVIRONMENT, OpenlitConfig.environment
335
+ )
336
+
337
+ except Exception as meta_exception:
338
+ logging.error(
339
+ "Failed to set metadata for %s: %s",
340
+ wrapped.__name__,
341
+ meta_exception,
342
+ exc_info=True,
343
+ )
344
+
345
+ return response
346
+
347
+ return wrapper
348
+
349
+
350
+ class TracedSpan:
351
+ """
352
+ A wrapper class for an OpenTelemetry span that provides helper methods
353
+ for setting result and metadata attributes on the span.
354
+
355
+ Attributes:
356
+ _span (Span): The underlying OpenTelemetry span.
357
+ """
358
+
359
+ def __init__(self, span):
360
+ """
361
+ Initializes the TracedSpan with the given span.
362
+
363
+ Params:
364
+ span (Span): The OpenTelemetry span to be wrapped.
365
+ """
366
+
367
+ self._span: Span = span
368
+
369
+ def set_result(self, result):
370
+ """
371
+ Sets the result attribute on the underlying span.
372
+
373
+ Params:
374
+ result: The result to be set as an attribute on the span.
375
+ """
376
+
377
+ self._span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION, result)
378
+
379
+ def set_metadata(self, metadata: Dict):
380
+ """
381
+ Sets multiple attributes on the underlying span.
382
+
383
+ Params:
384
+ metadata (Dict): A dictionary of attributes to be set on the span.
385
+ """
386
+
387
+ self._span.set_attributes(attributes=metadata)
388
+
389
+ def __enter__(self):
390
+ """
391
+ Enters the context of the TracedSpan, returning itself.
392
+
393
+ Returns:
394
+ TracedSpan: The instance of TracedSpan.
395
+ """
396
+
397
+ return self
398
+
399
+ def __exit__(self, _exc_type, _exc_val, _exc_tb):
400
+ """
401
+ Exits the context of the TracedSpan by ending the underlying span.
402
+ """
403
+
404
+ self._span.end()
405
+
406
+
407
+ @contextmanager
408
+ def start_trace(name: str):
409
+ """
410
+ A context manager that starts a new trace and provides a TracedSpan
411
+ for usage within the context.
412
+
413
+ Params:
414
+ name (str): The name of the span.
415
+
416
+ Yields:
417
+ TracedSpan: The wrapped span for trace operations.
418
+ """
419
+
420
+ __trace = t.get_tracer_provider()
421
+ with __trace.get_tracer(__name__).start_as_current_span(
422
+ name,
423
+ kind=SpanKind.CLIENT,
424
+ ) as span:
425
+ yield TracedSpan(span)
@@ -0,0 +1,52 @@
1
+ # pylint: disable=useless-return, bad-staticmethod-argument, disable=duplicate-code
2
+ """Initializer of Auto Instrumentation of GPT4All Functions"""
3
+
4
+ from typing import Collection
5
+ import importlib.metadata
6
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
7
+ from wrapt import wrap_function_wrapper
8
+
9
+ from openlit.instrumentation.gpt4all.gpt4all import (
10
+ embed, generate
11
+ )
12
+
13
+ _instruments = ("gpt4all >= 2.6.0",)
14
+
15
+ class GPT4AllInstrumentor(BaseInstrumentor):
16
+ """
17
+ An instrumentor for GPT4All's client library.
18
+ """
19
+
20
+ def instrumentation_dependencies(self) -> Collection[str]:
21
+ return _instruments
22
+
23
+ def _instrument(self, **kwargs):
24
+ application_name = kwargs.get("application_name", "default_application")
25
+ environment = kwargs.get("environment", "default_environment")
26
+ tracer = kwargs.get("tracer")
27
+ metrics = kwargs.get("metrics_dict")
28
+ pricing_info = kwargs.get("pricing_info", {})
29
+ trace_content = kwargs.get("trace_content", False)
30
+ disable_metrics = kwargs.get("disable_metrics")
31
+ version = importlib.metadata.version("gpt4all")
32
+
33
+ # generate
34
+ wrap_function_wrapper(
35
+ "gpt4all",
36
+ "GPT4All.generate",
37
+ generate("gpt4all.generate", version, environment, application_name,
38
+ tracer, pricing_info, trace_content, metrics, disable_metrics),
39
+ )
40
+
41
+ # embed
42
+ wrap_function_wrapper(
43
+ "gpt4all",
44
+ "Embed4All.embed",
45
+ embed("gpt4all.embed", version, environment, application_name,
46
+ tracer, pricing_info, trace_content, metrics, disable_metrics),
47
+ )
48
+
49
+
50
+ def _uninstrument(self, **kwargs):
51
+ # Proper uninstrumentation logic to revert patched methods
52
+ pass
@@ -0,0 +1,352 @@
1
+ # pylint: disable=duplicate-code, broad-exception-caught, too-many-statements, unused-argument, possibly-used-before-assignment
2
+ """
3
+ Module for monitoring GPT4All API calls.
4
+ """
5
+
6
+ import logging
7
+ from opentelemetry.trace import SpanKind, Status, StatusCode
8
+ from opentelemetry.sdk.resources import TELEMETRY_SDK_NAME
9
+ from openlit.__helpers import handle_exception, general_tokens
10
+ from openlit.semcov import SemanticConvetion
11
+
12
+ # Initialize logger for logging potential issues and operations
13
+ logger = logging.getLogger(__name__)
14
+
15
+ def generate(gen_ai_endpoint, version, environment, application_name,
16
+ tracer, pricing_info, trace_content, metrics, disable_metrics):
17
+ """
18
+ Generates a telemetry wrapper for generate to collect metrics.
19
+
20
+ Args:
21
+ gen_ai_endpoint: Endpoint identifier for logging and tracing.
22
+ version: Version of the monitoring package.
23
+ environment: Deployment environment (e.g., production, staging).
24
+ application_name: Name of the application using the GPT4All API.
25
+ tracer: OpenTelemetry tracer for creating spans.
26
+ pricing_info: Information used for calculating the cost of GPT4All usage.
27
+ trace_content: Flag indicating whether to trace the actual content.
28
+
29
+ Returns:
30
+ A function that wraps the generate method to add telemetry.
31
+ """
32
+
33
+ def wrapper(wrapped, instance, args, kwargs):
34
+ """
35
+ Wraps the 'generate' API call to add telemetry.
36
+
37
+ This collects metrics such as execution time, cost, and token usage, and handles errors
38
+ gracefully, adding details to the trace for observability.
39
+
40
+ Args:
41
+ wrapped: The original 'generate' method to be wrapped.
42
+ instance: The instance of the class where the original method is defined.
43
+ args: Positional arguments for the 'generate' method.
44
+ kwargs: Keyword arguments for the 'generate' method.
45
+
46
+ Returns:
47
+ The response from the original 'generate' method.
48
+ """
49
+
50
+ # Check if streaming is enabled for the API call
51
+ streaming = kwargs.get("streaming", False)
52
+
53
+ # pylint: disable=no-else-return
54
+ if streaming:
55
+ # Special handling for streaming response to accommodate the nature of data flow
56
+ def stream_generator():
57
+ with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
58
+ # Placeholder for aggregating streaming response
59
+ llmresponse = ""
60
+
61
+ # Loop through streaming events capturing relevant details
62
+ for chunk in wrapped(*args, **kwargs):
63
+ # Collect aggregated response from events
64
+ llmresponse += chunk
65
+
66
+ yield chunk
67
+
68
+ # Handling exception ensure observability without disrupting operation
69
+ try:
70
+ # Calculate cost of the operation
71
+ cost = 0
72
+
73
+ # pylint: disable=line-too-long
74
+ model = str(instance.model.model_path).rsplit('/', maxsplit=1)[-1] or "orca-mini-3b-gguf2-q4_0.gguf"
75
+ prompt = kwargs.get("prompt") or args[0] or ""
76
+
77
+ # Calculate cost of the operation
78
+ cost = 0
79
+ prompt_tokens = general_tokens(prompt)
80
+ completion_tokens = general_tokens(llmresponse)
81
+ total_tokens = prompt_tokens + completion_tokens
82
+
83
+ # Set base span attribues
84
+ span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
85
+ span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
86
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
87
+ span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
88
+ SemanticConvetion.GEN_AI_TYPE_CHAT)
89
+ span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
90
+ gen_ai_endpoint)
91
+ span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
92
+ environment)
93
+ span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
94
+ application_name)
95
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
96
+ model)
97
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_K,
98
+ kwargs.get("top_k", 40))
99
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_P,
100
+ kwargs.get("top_p", 0.4))
101
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MAX_TOKENS,
102
+ kwargs.get("max_tokens", 200))
103
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TEMPERATURE,
104
+ kwargs.get("temperature", 0.7))
105
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_FREQUENCY_PENALTY,
106
+ kwargs.get("frequency_penalty", 1.18))
107
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_IS_STREAM,
108
+ True)
109
+ if trace_content:
110
+ span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
111
+ prompt)
112
+ span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION,
113
+ llmresponse)
114
+
115
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
116
+ prompt_tokens)
117
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COMPLETION_TOKENS,
118
+ completion_tokens)
119
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
120
+ total_tokens)
121
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
122
+ cost)
123
+
124
+ span.set_status(Status(StatusCode.OK))
125
+
126
+ if disable_metrics is False:
127
+ attributes = {
128
+ TELEMETRY_SDK_NAME:
129
+ "openlit",
130
+ SemanticConvetion.GEN_AI_APPLICATION_NAME:
131
+ application_name,
132
+ SemanticConvetion.GEN_AI_SYSTEM:
133
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
134
+ SemanticConvetion.GEN_AI_ENVIRONMENT:
135
+ environment,
136
+ SemanticConvetion.GEN_AI_TYPE:
137
+ SemanticConvetion.GEN_AI_TYPE_CHAT,
138
+ SemanticConvetion.GEN_AI_REQUEST_MODEL:
139
+ model
140
+ }
141
+
142
+ metrics["genai_requests"].add(1, attributes)
143
+ metrics["genai_total_tokens"].add(total_tokens, attributes)
144
+ metrics["genai_completion_tokens"].add(completion_tokens, attributes)
145
+ metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
146
+ metrics["genai_cost"].record(cost, attributes)
147
+
148
+ except Exception as e:
149
+ handle_exception(span, e)
150
+ logger.error("Error in trace creation: %s", e)
151
+
152
+ return stream_generator()
153
+
154
+ # Handling for non-streaming responses
155
+ else:
156
+ # pylint: disable=line-too-long
157
+ with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
158
+ response = wrapped(*args, **kwargs)
159
+
160
+ # pylint: disable=line-too-long
161
+ model = str(instance.model.model_path).rsplit('/', maxsplit=1)[-1] or "orca-mini-3b-gguf2-q4_0.gguf"
162
+ prompt = kwargs.get("prompt") or args[0] or ""
163
+
164
+ # Calculate cost of the operation
165
+ cost = 0
166
+ prompt_tokens = general_tokens(prompt)
167
+ completion_tokens = general_tokens(response)
168
+ total_tokens = prompt_tokens + completion_tokens
169
+
170
+ try:
171
+ # Set base span attribues
172
+ span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
173
+ span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
174
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
175
+ span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
176
+ SemanticConvetion.GEN_AI_TYPE_CHAT)
177
+ span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
178
+ gen_ai_endpoint)
179
+ span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
180
+ environment)
181
+ span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
182
+ application_name)
183
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
184
+ model)
185
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_K,
186
+ kwargs.get("top_k", 40))
187
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_P,
188
+ kwargs.get("top_p", 0.4))
189
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MAX_TOKENS,
190
+ kwargs.get("max_tokens", 200))
191
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TEMPERATURE,
192
+ kwargs.get("temperature", 0.7))
193
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_FREQUENCY_PENALTY,
194
+ kwargs.get("frequency_penalty", 1.18))
195
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_IS_STREAM,
196
+ False)
197
+ if trace_content:
198
+ span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
199
+ prompt)
200
+ span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION,
201
+ response)
202
+
203
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
204
+ prompt_tokens)
205
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COMPLETION_TOKENS,
206
+ completion_tokens)
207
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
208
+ total_tokens)
209
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
210
+ cost)
211
+
212
+ span.set_status(Status(StatusCode.OK))
213
+
214
+ if disable_metrics is False:
215
+ attributes = {
216
+ TELEMETRY_SDK_NAME:
217
+ "openlit",
218
+ SemanticConvetion.GEN_AI_APPLICATION_NAME:
219
+ application_name,
220
+ SemanticConvetion.GEN_AI_SYSTEM:
221
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
222
+ SemanticConvetion.GEN_AI_ENVIRONMENT:
223
+ environment,
224
+ SemanticConvetion.GEN_AI_TYPE:
225
+ SemanticConvetion.GEN_AI_TYPE_CHAT,
226
+ SemanticConvetion.GEN_AI_REQUEST_MODEL:
227
+ model
228
+ }
229
+
230
+ metrics["genai_requests"].add(1, attributes)
231
+ metrics["genai_total_tokens"].add(total_tokens, attributes)
232
+ metrics["genai_completion_tokens"].add(completion_tokens, attributes)
233
+ metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
234
+ metrics["genai_cost"].record(cost, attributes)
235
+
236
+ # Return original response
237
+ return response
238
+
239
+ except Exception as e:
240
+ handle_exception(span, e)
241
+ logger.error("Error in trace creation: %s", e)
242
+
243
+ # Return original response
244
+ return response
245
+
246
+ return wrapper
247
+
248
+ def embed(gen_ai_endpoint, version, environment, application_name,
249
+ tracer, pricing_info, trace_content, metrics, disable_metrics):
250
+ """
251
+ Generates a telemetry wrapper for embeddings to collect metrics.
252
+
253
+ Args:
254
+ gen_ai_endpoint: Endpoint identifier for logging and tracing.
255
+ version: Version of the monitoring package.
256
+ environment: Deployment environment (e.g., production, staging).
257
+ application_name: Name of the application using the GPT4All API.
258
+ tracer: OpenTelemetry tracer for creating spans.
259
+ pricing_info: Information used for calculating the cost of GPT4All usage.
260
+ trace_content: Flag indicating whether to trace the actual content.
261
+
262
+ Returns:
263
+ A function that wraps the embeddings method to add telemetry.
264
+ """
265
+
266
+ def wrapper(wrapped, instance, args, kwargs):
267
+ """
268
+ Wraps the 'embeddings' API call to add telemetry.
269
+
270
+ This collects metrics such as execution time, cost, and token usage, and handles errors
271
+ gracefully, adding details to the trace for observability.
272
+
273
+ Args:
274
+ wrapped: The original 'embeddings' method to be wrapped.
275
+ instance: The instance of the class where the original method is defined.
276
+ args: Positional arguments for the 'embeddings' method.
277
+ kwargs: Keyword arguments for the 'embeddings' method.
278
+
279
+ Returns:
280
+ The response from the original 'embeddings' method.
281
+ """
282
+
283
+ with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
284
+ response = wrapped(*args, **kwargs)
285
+
286
+ try:
287
+ # pylint: disable=line-too-long
288
+ model = str(instance.gpt4all.model.model_path).rsplit('/', maxsplit=1)[-1] or "all-MiniLM-L6-v2.gguf2.f16.gguf"
289
+ prompt = kwargs.get("prompt") or args[0] or ""
290
+
291
+ # Calculate cost of the operation
292
+ cost = 0
293
+ prompt_tokens = general_tokens(prompt)
294
+
295
+ # Set Span attributes
296
+ span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
297
+ span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
298
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
299
+ span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
300
+ SemanticConvetion.GEN_AI_TYPE_EMBEDDING)
301
+ span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
302
+ gen_ai_endpoint)
303
+ span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
304
+ environment)
305
+ span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
306
+ application_name)
307
+ span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
308
+ model)
309
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
310
+ prompt_tokens)
311
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
312
+ prompt_tokens)
313
+ span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
314
+ cost)
315
+ if trace_content:
316
+ span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
317
+ prompt)
318
+
319
+ span.set_status(Status(StatusCode.OK))
320
+
321
+ if disable_metrics is False:
322
+ attributes = {
323
+ TELEMETRY_SDK_NAME:
324
+ "openlit",
325
+ SemanticConvetion.GEN_AI_APPLICATION_NAME:
326
+ application_name,
327
+ SemanticConvetion.GEN_AI_SYSTEM:
328
+ SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
329
+ SemanticConvetion.GEN_AI_ENVIRONMENT:
330
+ environment,
331
+ SemanticConvetion.GEN_AI_TYPE:
332
+ SemanticConvetion.GEN_AI_TYPE_EMBEDDING,
333
+ SemanticConvetion.GEN_AI_REQUEST_MODEL:
334
+ model
335
+ }
336
+
337
+ metrics["genai_requests"].add(1, attributes)
338
+ metrics["genai_total_tokens"].add(prompt_tokens, attributes)
339
+ metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
340
+ metrics["genai_cost"].record(cost, attributes)
341
+
342
+ # Return original response
343
+ return response
344
+
345
+ except Exception as e:
346
+ handle_exception(span, e)
347
+ logger.error("Error in trace creation: %s", e)
348
+
349
+ # Return original response
350
+ return response
351
+
352
+ return wrapper
@@ -268,7 +268,7 @@ def async_chat(gen_ai_endpoint, version, environment, application_name,
268
268
  else:
269
269
  i = 0
270
270
  while i < kwargs["n"] and trace_content is True:
271
- attribute_name = f"gen_ai.content.completion.{i}"
271
+ attribute_name = f"gen_ai.completion.{i}"
272
272
  span.set_attribute(attribute_name,
273
273
  response.choices[i].message.content)
274
274
  i += 1
@@ -268,7 +268,7 @@ def chat(gen_ai_endpoint, version, environment, application_name,
268
268
  else:
269
269
  i = 0
270
270
  while i < kwargs["n"] and trace_content is True:
271
- attribute_name = f"gen_ai.content.completion.{i}"
271
+ attribute_name = f"gen_ai.completion.{i}"
272
272
  span.set_attribute(attribute_name,
273
273
  response.choices[i].message.content)
274
274
  i += 1
@@ -269,7 +269,7 @@ def azure_async_chat_completions(gen_ai_endpoint, version, environment, applicat
269
269
  else:
270
270
  i = 0
271
271
  while i < kwargs["n"] and trace_content is True:
272
- attribute_name = f"gen_ai.content.completion.{i}"
272
+ attribute_name = f"gen_ai.completion.{i}"
273
273
  span.set_attribute(attribute_name,
274
274
  response.choices[i].message.content)
275
275
  i += 1
@@ -550,7 +550,7 @@ def azure_async_completions(gen_ai_endpoint, version, environment, application_n
550
550
  else:
551
551
  i = 0
552
552
  while i < kwargs["n"] and trace_content is True:
553
- attribute_name = f"gen_ai.content.completion.{i}"
553
+ attribute_name = f"gen_ai.completion.{i}"
554
554
  span.set_attribute(attribute_name,
555
555
  response.choices[i].text)
556
556
  i += 1
@@ -273,7 +273,7 @@ def async_chat_completions(gen_ai_endpoint, version, environment, application_na
273
273
  else:
274
274
  i = 0
275
275
  while i < kwargs["n"] and trace_content is True:
276
- attribute_name = f"gen_ai.content.completion.{i}"
276
+ attribute_name = f"gen_ai.completion.{i}"
277
277
  span.set_attribute(attribute_name,
278
278
  response.choices[i].message.content)
279
279
  i += 1
@@ -269,7 +269,7 @@ def azure_chat_completions(gen_ai_endpoint, version, environment, application_na
269
269
  else:
270
270
  i = 0
271
271
  while i < kwargs["n"] and trace_content is True:
272
- attribute_name = f"gen_ai.content.completion.{i}"
272
+ attribute_name = f"gen_ai.completion.{i}"
273
273
  span.set_attribute(attribute_name,
274
274
  response.choices[i].message.content)
275
275
  i += 1
@@ -548,7 +548,7 @@ def azure_completions(gen_ai_endpoint, version, environment, application_name,
548
548
  else:
549
549
  i = 0
550
550
  while i < kwargs["n"] and trace_content is True:
551
- attribute_name = f"gen_ai.content.completion.{i}"
551
+ attribute_name = f"gen_ai.completion.{i}"
552
552
  span.set_attribute(attribute_name,
553
553
  response.choices[i].text)
554
554
  i += 1
@@ -272,7 +272,7 @@ def chat_completions(gen_ai_endpoint, version, environment, application_name,
272
272
  else:
273
273
  i = 0
274
274
  while i < kwargs["n"] and trace_content is True:
275
- attribute_name = f"gen_ai.content.completion.{i}"
275
+ attribute_name = f"gen_ai.completion.{i}"
276
276
  span.set_attribute(attribute_name,
277
277
  response.choices[i].message.content)
278
278
  i += 1
@@ -98,7 +98,7 @@ def text_wrap(gen_ai_endpoint, version, environment, application_name,
98
98
  completion_tokens = 0
99
99
  for completion in response:
100
100
  if len(response) > 1:
101
- attribute_name = f"gen_ai.content.completion.{i}"
101
+ attribute_name = f"gen_ai.completion.{i}"
102
102
  else:
103
103
  attribute_name = SemanticConvetion.GEN_AI_CONTENT_COMPLETION
104
104
  if i == 0:
@@ -21,7 +21,7 @@ class SemanticConvetion:
21
21
  GEN_AI_SYSTEM = "gen_ai.system"
22
22
  GEN_AI_ENVIRONMENT = "gen_ai.environment"
23
23
  GEN_AI_APPLICATION_NAME = "gen_ai.application_name"
24
- GEN_AI_TYPE = "gen_ai.type"
24
+ GEN_AI_TYPE = "gen_ai.operation.name"
25
25
  GEN_AI_HUB_OWNER = "gen_ai.hub.owner"
26
26
  GEN_AI_HUB_REPO = "gen_ai.hub.repo"
27
27
  GEN_AI_RETRIEVAL_SOURCE = "gen_ai.retrieval.source"
@@ -68,8 +68,8 @@ class SemanticConvetion:
68
68
  GEN_AI_RESPONSE_IMAGE_STYLE = "gen_ai.request.image_style"
69
69
 
70
70
  # GenAI Content
71
- GEN_AI_CONTENT_PROMPT = "gen_ai.content.prompt"
72
- GEN_AI_CONTENT_COMPLETION = "gen_ai.content.completion"
71
+ GEN_AI_CONTENT_PROMPT = "gen_ai.prompt"
72
+ GEN_AI_CONTENT_COMPLETION = "gen_ai.completion"
73
73
  GEN_AI_CONTENT_REVISED_PROMPT = "gen_ai.content.revised_prompt"
74
74
 
75
75
  # GenAI Evaluation Metrics
@@ -95,6 +95,7 @@ class SemanticConvetion:
95
95
  GEN_AI_SYSTEM_VERTEXAI = "vertexai"
96
96
  GEN_AI_SYSTEM_GROQ = "groq"
97
97
  GEN_AI_SYSTEM_OLLAMA = "ollama"
98
+ GEN_AI_SYSTEM_GPT4ALL = "gpt4all"
98
99
  GEN_AI_SYSTEM_LANGCHAIN = "langchain"
99
100
  GEN_AI_SYSTEM_LLAMAINDEX = "llama_index"
100
101
  GEN_AI_SYSTEM_HAYSTACK = "haystack"
File without changes