Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4d717b1
Merge branch 'development' into release
karthikscale3 Apr 24, 2024
0233826
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Apr 28, 2024
7f4e951
Merge branch 'development' into release
karthikscale3 Apr 28, 2024
81a6ca0
Merge
karthikscale3 Jun 13, 2024
0c19f77
Merge branch 'development' into release
karthikscale3 Jun 13, 2024
c3a6ccf
remove logs
karthikscale3 Jun 13, 2024
a99cf10
remove requirements
karthikscale3 Jun 13, 2024
1379b27
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Jun 17, 2024
dae04e7
Merge branch 'development' into release
karthikscale3 Jun 17, 2024
129e927
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Jun 24, 2024
16e67f9
Merge branch 'development' into release
karthikscale3 Jun 24, 2024
e604e93
Bump version
karthikscale3 Jun 24, 2024
7e00473
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Jun 24, 2024
6ac71aa
Merge branch 'development' into release
karthikscale3 Jun 24, 2024
c39bf01
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Jun 24, 2024
f89e38c
Merge branch 'development' into release
karthikscale3 Jun 24, 2024
e95e743
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Jul 19, 2024
c62e803
Squash
karthikscale3 Jul 25, 2024
d7fd3fb
Merge
karthikscale3 Jul 25, 2024
c4ea507
Merge branch 'development' into release
karthikscale3 Jul 25, 2024
4c74fd8
Merge
karthikscale3 Jul 31, 2024
9a83e20
Merge branch 'development' into release
karthikscale3 Jul 31, 2024
09d5631
Merge
karthikscale3 Aug 3, 2024
508e72b
Merge
karthikscale3 Aug 3, 2024
ad44fa3
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Aug 13, 2024
ad168b3
Merge branch 'development' into release
karthikscale3 Aug 13, 2024
cbb2665
CrewAI enhancements and embedchain support (#313)
karthikscale3 Aug 30, 2024
6876f92
Merge branch 'main' of github.com:Scale3-Labs/langtrace-python-sdk in…
karthikscale3 Aug 30, 2024
630169a
Merge branch 'development' into release
karthikscale3 Aug 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ Langtrace automatically captures traces from the following vendors:
| Ollama | Framework | :x: | :white_check_mark: |
| VertexAI | Framework | :x: | :white_check_mark: |
| Vercel AI SDK| Framework | :white_check_mark: | :x: |
| EmbedChain | Framework | :x: | :white_check_mark: |
| Pinecone | Vector Database | :white_check_mark: | :white_check_mark: |
| ChromaDB | Vector Database | :white_check_mark: | :white_check_mark: |
| QDrant | Vector Database | :white_check_mark: | :white_check_mark: |
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dev = [
"google-generativeai",
"google-cloud-aiplatform",
"mistralai",
"embedchain",
]

test = ["pytest", "pytest-vcr", "pytest-asyncio"]
Expand Down
31 changes: 27 additions & 4 deletions src/examples/crewai_example/simple_agent/agents.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from crewai import Agent
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_cohere import ChatCohere
from langchain_ollama import ChatOllama
from langchain_openai import ChatOpenAI


class PoetryAgents:
def __init__(self):
self.open_ai = ChatOpenAI(
model_name="gpt-4", temperature=0.7, stream_usage=True
)
self.open_ai = ChatOpenAI(model_name="gpt-4", temperature=0.7)
self.anthropic = ChatAnthropic(
model_name="claude-3-5-sonnet-20240620", temperature=0.7
)
Expand All @@ -30,3 +28,28 @@ def create_poet_agent(self):
verbose=True,
llm=self.open_ai,
)

def poet_agent_2(self):
return Agent(
role="Renaissance Poet",
backstory="""
I am a Renaissance Poet. I am well-versed in the art of poetry and have a deep appreciation for the beauty of language and expression.
""",
goal="""Create a poem that is inspired by the works of the Renaissance poets""",
allow_delegation=False,
verbose=True,
llm=self.open_ai,
)

def poet_agent_3(self):
return Agent(
role="William Shakespeare",
backstory="""
I am william shakespeare. I am an Expert in poetry writing and creative expression.
I have been writing poetry for over 10 years and have published several collections.
""",
goal="""Create a poem that is inspired by the works of William Shakespeare""",
allow_delegation=False,
verbose=True,
llm=self.open_ai,
)
13 changes: 9 additions & 4 deletions src/examples/crewai_example/simple_agent/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from agents import PoetryAgents
from crewai import Crew
from .agents import PoetryAgents
from .tasks import PoetryTasks
from langtrace_python_sdk import langtrace
from dotenv import load_dotenv
from tasks import PoetryTasks

from langtrace_python_sdk import langtrace

load_dotenv()
langtrace.init()
Expand All @@ -17,10 +18,14 @@ def run(self):
tasks = PoetryTasks()

poetry_agent = agents.create_poet_agent()
poetry_agent_2 = agents.poet_agent_2()
poetry_agent_3 = agents.poet_agent_3()

create_poem = tasks.create_poem(poetry_agent, self.topic)
create_poem_2 = tasks.create_poem(poetry_agent_2, self.topic)
create_poem_3 = tasks.create_poem(poetry_agent_3, self.topic)

crew = Crew(agents=[poetry_agent], tasks=[create_poem], verbose=True)
crew = Crew(agents=[poetry_agent], tasks=[create_poem], verbose=True, memory=True)
res = crew.kickoff()
return res

Expand Down
15 changes: 15 additions & 0 deletions src/examples/embedchain_example/simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from dotenv import load_dotenv
from embedchain import App
from langtrace_python_sdk import langtrace

load_dotenv()
langtrace.init()

app = App()
app.reset()
app.add("https://www.forbes.com/profile/elon-musk")
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
res = app.query("What is the net worth of Elon Musk today?")
print(res)
re2 = app.search("Elon Musk")
print(re2)
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"VERTEXAI": "VertexAI",
"GEMINI": "Gemini",
"MISTRAL": "Mistral",
"EMBEDCHAIN": "Embedchain",
}

LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY = "langtrace_additional_attributes"
14 changes: 14 additions & 0 deletions src/langtrace_python_sdk/constants/instrumentation/embedchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
APIS = {
"ADD": {
"METHOD": "embedchain.add",
"OPERATION": "add",
},
"QUERY": {
"METHOD": "embedchain.query",
"OPERATION": "query",
},
"SEARCH": {
"METHOD": "embedchain.search",
"OPERATION": "search",
},
}
2 changes: 2 additions & 0 deletions src/langtrace_python_sdk/instrumentation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
from .vertexai import VertexAIInstrumentation
from .gemini import GeminiInstrumentation
from .mistral import MistralInstrumentation
from .embedchain import EmbedchainInstrumentation

__all__ = [
"AnthropicInstrumentation",
"ChromaInstrumentation",
"CohereInstrumentation",
"CrewAIInstrumentation",
"EmbedchainInstrumentation",
"GroqInstrumentation",
"LangchainInstrumentation",
"LangchainCommunityInstrumentation",
Expand Down
2 changes: 1 addition & 1 deletion src/langtrace_python_sdk/instrumentation/chroma/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def traced_method(wrapped, instance, args, kwargs):
"langtrace.version": v(LANGTRACE_SDK_NAME),
"db.system": "chromadb",
"db.operation": api["OPERATION"],
"db.query": json.dumps(kwargs.get("query")),
"db.query": json.dumps(kwargs),
**(extra_attributes if extra_attributes is not None else {}),
}

Expand Down
13 changes: 12 additions & 1 deletion src/langtrace_python_sdk/instrumentation/crewai/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,23 @@ def traced_method(wrapped, instance, args, kwargs):
result = wrapped(*args, **kwargs)
if result:
span.set_status(Status(StatusCode.OK))
if instance.__class__.__name__ == "Crew":
span.set_attribute("crewai.crew.result", str(result))
if hasattr(result, "tasks_output"):
span.set_attribute("crewai.crew.tasks_output", str((result.tasks_output)))
if hasattr(result, "token_usage"):
span.set_attribute("crewai.crew.token_usage", str((result.token_usage)))
if hasattr(result, "usage_metrics"):
span.set_attribute("crewai.crew.usage_metrics", str((result.usage_metrics)))
elif instance.__class__.__name__ == "Agent":
span.set_attribute("crewai.agent.result", str(result))
elif instance.__class__.__name__ == "Task":
span.set_attribute("crewai.task.result", str(result))

span.end()
return result

except Exception as err:
print("Error", err)
# Record the exception in the span
span.record_exception(err)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .instrumentation import EmbedchainInstrumentation

__all__ = [
"EmbedchainInstrumentation",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
Copyright (c) 2024 Scale3 Labs

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import importlib.metadata
import logging
from typing import Collection

from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
from opentelemetry.trace import get_tracer
from wrapt import wrap_function_wrapper

from langtrace_python_sdk.instrumentation.embedchain.patch import generic_patch

logging.basicConfig(level=logging.FATAL)


class EmbedchainInstrumentation(BaseInstrumentor):
"""
The EmbedchainInstrumentation class represents the Embedchain instrumentation
"""

def instrumentation_dependencies(self) -> Collection[str]:
return ["embedchain >= 0.1.113"]

def _instrument(self, **kwargs):
tracer_provider = kwargs.get("tracer_provider")
tracer = get_tracer(__name__, "", tracer_provider)
version = importlib.metadata.version("embedchain")

wrap_function_wrapper(
"embedchain.embedchain",
"EmbedChain.add",
generic_patch("ADD", version, tracer),
)

wrap_function_wrapper(
"embedchain.embedchain",
"EmbedChain.query",
generic_patch("QUERY", version, tracer),
)

wrap_function_wrapper(
"embedchain.embedchain",
"EmbedChain.search",
generic_patch("SEARCH", version, tracer),
)

def _instrument_module(self, module_name):
pass

def _uninstrument(self, **kwargs):
pass
91 changes: 91 additions & 0 deletions src/langtrace_python_sdk/instrumentation/embedchain/patch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""
Copyright (c) 2024 Scale3 Labs

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from langtrace.trace_attributes import FrameworkSpanAttributes
from langtrace_python_sdk.utils import set_span_attribute
from langtrace_python_sdk.utils.llm import get_span_name
from opentelemetry import baggage, trace
from opentelemetry.trace import SpanKind
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.trace.propagation import set_span_in_context
from langtrace_python_sdk.constants.instrumentation.embedchain import APIS
from langtrace_python_sdk.constants.instrumentation.common import (
LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
SERVICE_PROVIDERS,
)
import json
from importlib_metadata import version as v

from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME


def generic_patch(method, version, tracer):
"""
A generic patch method that wraps a function with a span
"""

def traced_method(wrapped, instance, args, kwargs):
api = APIS[method]
service_provider = SERVICE_PROVIDERS["EMBEDCHAIN"]
extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)

span_attributes = {
"langtrace.sdk.name": "langtrace-python-sdk",
"langtrace.service.name": service_provider,
"langtrace.service.type": "framework",
"langtrace.service.version": version,
"langtrace.version": v(LANGTRACE_SDK_NAME),
"embedchain.api": api["OPERATION"],
**(extra_attributes if extra_attributes is not None else {}),
}

if len(args) > 0:
span_attributes["embedchain.inputs"] = json.dumps(args)

attributes = FrameworkSpanAttributes(**span_attributes)

with tracer.start_as_current_span(
name=get_span_name(api["METHOD"]),
kind=SpanKind.CLIENT,
context=set_span_in_context(trace.get_current_span()),
) as span:
for field, value in attributes.model_dump(by_alias=True).items():
if value is not None:
span.set_attribute(field, value)
try:
result = wrapped(*args, **kwargs)
set_span_attribute(span, "embedchain.outputs", json.dumps(result))
span.set_status(StatusCode.OK)
return result
except Exception as err:
# Record the exception in the span
span.record_exception(err)

# Set the span status to indicate an error
span.set_status(Status(StatusCode.ERROR, str(err)))

# Reraise the exception to ensure it's not swallowed
raise

return traced_method


def get_count_or_none(value):
return len(value) if value is not None else None


def handle_null_params(param):
return str(param) if param else None
2 changes: 2 additions & 0 deletions src/langtrace_python_sdk/langtrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
ChromaInstrumentation,
CohereInstrumentation,
CrewAIInstrumentation,
EmbedchainInstrumentation,
GroqInstrumentation,
LangchainInstrumentation,
LangchainCommunityInstrumentation,
Expand Down Expand Up @@ -115,6 +116,7 @@ def init(
"pinecone": PineconeInstrumentation(),
"llamaindex": LlamaindexInstrumentation(),
"chroma": ChromaInstrumentation(),
"embedchain": EmbedchainInstrumentation(),
"qdrant": QdrantInstrumentation(),
"langchain": LangchainInstrumentation(),
"langchain_core": LangchainCoreInstrumentation(),
Expand Down
2 changes: 1 addition & 1 deletion src/langtrace_python_sdk/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.2.31"
__version__ = "2.3.0"