langtrace-python-sdk 1.3.6__py3-none-any.whl → 2.0.0__py3-none-any.whl
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.
- examples/anthropic_example/completion.py +6 -6
- examples/cohere_example/chat.py +5 -4
- examples/cohere_example/chat_stream.py +2 -4
- examples/cohere_example/{embed_create.py → embed.py} +4 -3
- examples/cohere_example/rerank.py +31 -0
- examples/cohere_example/tools.py +40 -0
- examples/openai_example/chat_completion.py +41 -0
- examples/{openai → openai_example}/embeddings_create.py +3 -2
- examples/{openai → openai_example}/function_calling.py +3 -5
- examples/{openai → openai_example}/images_generate.py +1 -1
- examples/openai_example/tool_calling.py +67 -0
- examples/{openai → openai_example}/tool_calling_nonstreaming.py +2 -1
- langtrace_python_sdk/__init__.py +14 -1
- langtrace_python_sdk/constants/instrumentation/cohere.py +6 -1
- langtrace_python_sdk/instrumentation/anthropic/instrumentation.py +16 -4
- langtrace_python_sdk/instrumentation/anthropic/patch.py +26 -6
- langtrace_python_sdk/instrumentation/chroma/instrumentation.py +14 -2
- langtrace_python_sdk/instrumentation/chroma/patch.py +16 -4
- langtrace_python_sdk/instrumentation/cohere/instrumentation.py +24 -7
- langtrace_python_sdk/instrumentation/cohere/patch.py +295 -95
- langtrace_python_sdk/instrumentation/langchain/instrumentation.py +14 -3
- langtrace_python_sdk/instrumentation/langchain/patch.py +16 -4
- langtrace_python_sdk/instrumentation/langchain_community/instrumentation.py +15 -2
- langtrace_python_sdk/instrumentation/langchain_community/patch.py +20 -3
- langtrace_python_sdk/instrumentation/langchain_core/instrumentation.py +14 -4
- langtrace_python_sdk/instrumentation/langchain_core/patch.py +19 -7
- langtrace_python_sdk/instrumentation/llamaindex/instrumentation.py +15 -11
- langtrace_python_sdk/instrumentation/llamaindex/patch.py +20 -10
- langtrace_python_sdk/instrumentation/openai/instrumentation.py +20 -9
- langtrace_python_sdk/instrumentation/openai/patch.py +112 -78
- langtrace_python_sdk/instrumentation/pinecone/instrumentation.py +14 -3
- langtrace_python_sdk/instrumentation/pinecone/patch.py +17 -4
- langtrace_python_sdk/langtrace.py +40 -35
- langtrace_python_sdk/utils/llm.py +17 -4
- langtrace_python_sdk/utils/with_root_span.py +21 -5
- langtrace_python_sdk/version.py +1 -1
- {langtrace_python_sdk-1.3.6.dist-info → langtrace_python_sdk-2.0.0.dist-info}/METADATA +2 -2
- {langtrace_python_sdk-1.3.6.dist-info → langtrace_python_sdk-2.0.0.dist-info}/RECORD +53 -45
- tests/anthropic/cassettes/test_anthropic.yaml +85 -0
- tests/anthropic/cassettes/test_anthropic_streaming.yaml +456 -0
- tests/anthropic/cassettes/test_async_anthropic_streaming.yaml +328 -0
- tests/anthropic/conftest.py +38 -0
- tests/anthropic/test_anthropic.py +108 -72
- tests/conftest.py +17 -0
- tests/openai/conftest.py +5 -13
- tests/openai/test_chat_completion.py +21 -0
- tests/openai/test_image_generation.py +20 -8
- examples/openai/chat_completion.py +0 -58
- /examples/{openai → openai_example}/__init__.py +0 -0
- /examples/{openai → openai_example}/async_tool_calling_nonstreaming.py +0 -0
- /examples/{openai → openai_example}/async_tool_calling_streaming.py +0 -0
- /examples/{openai → openai_example}/tool_calling_streaming.py +0 -0
- {langtrace_python_sdk-1.3.6.dist-info → langtrace_python_sdk-2.0.0.dist-info}/WHEEL +0 -0
- {langtrace_python_sdk-1.3.6.dist-info → langtrace_python_sdk-2.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
3
15
|
"""
|
|
4
16
|
|
|
5
17
|
import importlib.metadata
|
|
@@ -11,9 +23,7 @@ from opentelemetry.trace import get_tracer
|
|
|
11
23
|
from wrapt import wrap_function_wrapper
|
|
12
24
|
|
|
13
25
|
from langtrace_python_sdk.instrumentation.langchain_core.patch import (
|
|
14
|
-
generic_patch,
|
|
15
|
-
runnable_patch,
|
|
16
|
-
)
|
|
26
|
+
generic_patch, runnable_patch)
|
|
17
27
|
|
|
18
28
|
|
|
19
29
|
# pylint: disable=dangerous-default-value
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
3
15
|
"""
|
|
4
16
|
|
|
5
17
|
import json
|
|
@@ -68,12 +80,12 @@ def generic_patch(
|
|
|
68
80
|
|
|
69
81
|
span.set_status(StatusCode.OK)
|
|
70
82
|
return result
|
|
71
|
-
except Exception as
|
|
83
|
+
except Exception as err:
|
|
72
84
|
# Record the exception in the span
|
|
73
|
-
span.record_exception(
|
|
85
|
+
span.record_exception(err)
|
|
74
86
|
|
|
75
87
|
# Set the span status to indicate an error
|
|
76
|
-
span.set_status(Status(StatusCode.ERROR, str(
|
|
88
|
+
span.set_status(Status(StatusCode.ERROR, str(err)))
|
|
77
89
|
|
|
78
90
|
# Reraise the exception to ensure it's not swallowed
|
|
79
91
|
raise
|
|
@@ -157,12 +169,12 @@ def runnable_patch(
|
|
|
157
169
|
|
|
158
170
|
span.set_status(StatusCode.OK)
|
|
159
171
|
return result
|
|
160
|
-
except Exception as
|
|
172
|
+
except Exception as err:
|
|
161
173
|
# Record the exception in the span
|
|
162
|
-
span.record_exception(
|
|
174
|
+
span.record_exception(err)
|
|
163
175
|
|
|
164
176
|
# Set the span status to indicate an error
|
|
165
|
-
span.set_status(Status(StatusCode.ERROR, str(
|
|
177
|
+
span.set_status(Status(StatusCode.ERROR, str(err)))
|
|
166
178
|
|
|
167
179
|
# Reraise the exception to ensure it's not swallowed
|
|
168
180
|
raise
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
3
15
|
"""
|
|
4
16
|
|
|
5
17
|
import importlib.metadata
|
|
6
18
|
import inspect
|
|
19
|
+
import logging
|
|
7
20
|
from typing import Collection
|
|
8
21
|
|
|
9
22
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
10
23
|
from opentelemetry.trace import get_tracer
|
|
11
24
|
from wrapt import wrap_function_wrapper
|
|
12
25
|
|
|
13
|
-
from langtrace_python_sdk.instrumentation.llamaindex.patch import
|
|
14
|
-
generic_patch,
|
|
15
|
-
async_generic_patch,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
import logging
|
|
19
|
-
|
|
20
|
-
logging.basicConfig(level=logging.FATAL)
|
|
21
|
-
|
|
22
|
-
import logging
|
|
26
|
+
from langtrace_python_sdk.instrumentation.llamaindex.patch import generic_patch
|
|
23
27
|
|
|
24
28
|
logging.basicConfig(level=logging.FATAL)
|
|
25
29
|
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
3
15
|
"""
|
|
4
16
|
|
|
5
17
|
from langtrace.trace_attributes import FrameworkSpanAttributes
|
|
@@ -8,9 +20,7 @@ from opentelemetry.trace import SpanKind
|
|
|
8
20
|
from opentelemetry.trace.status import Status, StatusCode
|
|
9
21
|
|
|
10
22
|
from langtrace_python_sdk.constants.instrumentation.common import (
|
|
11
|
-
LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
|
|
12
|
-
SERVICE_PROVIDERS,
|
|
13
|
-
)
|
|
23
|
+
LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY, SERVICE_PROVIDERS)
|
|
14
24
|
|
|
15
25
|
|
|
16
26
|
def generic_patch(method, task, tracer, version):
|
|
@@ -42,12 +52,12 @@ def generic_patch(method, task, tracer, version):
|
|
|
42
52
|
result = wrapped(*args, **kwargs)
|
|
43
53
|
span.set_status(StatusCode.OK)
|
|
44
54
|
return result
|
|
45
|
-
except Exception as
|
|
55
|
+
except Exception as err:
|
|
46
56
|
# Record the exception in the span
|
|
47
|
-
span.record_exception(
|
|
57
|
+
span.record_exception(err)
|
|
48
58
|
|
|
49
59
|
# Set the span status to indicate an error
|
|
50
|
-
span.set_status(Status(StatusCode.ERROR, str(
|
|
60
|
+
span.set_status(Status(StatusCode.ERROR, str(err)))
|
|
51
61
|
|
|
52
62
|
# Reraise the exception to ensure it's not swallowed
|
|
53
63
|
raise
|
|
@@ -84,12 +94,12 @@ def async_generic_patch(method, task, tracer, version):
|
|
|
84
94
|
result = await wrapped(*args, **kwargs)
|
|
85
95
|
span.set_status(StatusCode.OK)
|
|
86
96
|
return result
|
|
87
|
-
except Exception as
|
|
97
|
+
except Exception as err:
|
|
88
98
|
# Record the exception in the span
|
|
89
|
-
span.record_exception(
|
|
99
|
+
span.record_exception(err)
|
|
90
100
|
|
|
91
101
|
# Set the span status to indicate an error
|
|
92
|
-
span.set_status(Status(StatusCode.ERROR, str(
|
|
102
|
+
span.set_status(Status(StatusCode.ERROR, str(err)))
|
|
93
103
|
|
|
94
104
|
# Reraise the exception to ensure it's not swallowed
|
|
95
105
|
raise
|
|
@@ -1,4 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
"""
|
|
16
|
+
|
|
1
17
|
import importlib.metadata
|
|
18
|
+
import logging
|
|
2
19
|
from typing import Collection
|
|
3
20
|
|
|
4
21
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
@@ -6,15 +23,9 @@ from opentelemetry.trace import get_tracer
|
|
|
6
23
|
from wrapt import wrap_function_wrapper
|
|
7
24
|
|
|
8
25
|
from langtrace_python_sdk.instrumentation.openai.patch import (
|
|
9
|
-
async_embeddings_create,
|
|
10
|
-
async_images_generate,
|
|
11
|
-
|
|
12
|
-
embeddings_create,
|
|
13
|
-
images_generate,
|
|
14
|
-
async_chat_completions_create,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
import logging
|
|
26
|
+
async_chat_completions_create, async_embeddings_create,
|
|
27
|
+
async_images_generate, chat_completions_create, embeddings_create,
|
|
28
|
+
images_generate)
|
|
18
29
|
|
|
19
30
|
logging.basicConfig(level=logging.FATAL)
|
|
20
31
|
|
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
"""
|
|
3
16
|
|
|
4
17
|
import json
|
|
5
18
|
|
|
6
19
|
from langtrace.trace_attributes import Event, LLMSpanAttributes
|
|
7
|
-
from opentelemetry import baggage
|
|
20
|
+
from opentelemetry import baggage
|
|
8
21
|
from opentelemetry.trace import SpanKind
|
|
9
22
|
from opentelemetry.trace.status import Status, StatusCode
|
|
10
23
|
|
|
11
24
|
from langtrace_python_sdk.constants.instrumentation.common import (
|
|
12
|
-
LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
|
|
13
|
-
SERVICE_PROVIDERS,
|
|
14
|
-
)
|
|
25
|
+
LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY, SERVICE_PROVIDERS)
|
|
15
26
|
from langtrace_python_sdk.constants.instrumentation.openai import APIS
|
|
16
|
-
from langtrace_python_sdk.utils.llm import calculate_prompt_tokens,
|
|
27
|
+
from langtrace_python_sdk.utils.llm import (calculate_prompt_tokens,
|
|
28
|
+
estimate_tokens)
|
|
17
29
|
|
|
18
30
|
|
|
19
31
|
def images_generate(original_method, version, tracer):
|
|
@@ -40,7 +52,7 @@ def images_generate(original_method, version, tracer):
|
|
|
40
52
|
"llm.api": APIS["IMAGES_GENERATION"]["ENDPOINT"],
|
|
41
53
|
"llm.model": kwargs.get("model"),
|
|
42
54
|
"llm.stream": kwargs.get("stream"),
|
|
43
|
-
"llm.prompts": json.dumps([kwargs.get("prompt", [])]),
|
|
55
|
+
"llm.prompts": json.dumps([{"role": "user", "content": kwargs.get("prompt", [])}]),
|
|
44
56
|
**(extra_attributes if extra_attributes is not None else {}),
|
|
45
57
|
}
|
|
46
58
|
|
|
@@ -63,12 +75,15 @@ def images_generate(original_method, version, tracer):
|
|
|
63
75
|
)
|
|
64
76
|
response = [
|
|
65
77
|
{
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
data.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
"role": "assistant",
|
|
79
|
+
"content": {
|
|
80
|
+
"url": data.url if hasattr(data, "url") else "",
|
|
81
|
+
"revised_prompt": (
|
|
82
|
+
data.revised_prompt
|
|
83
|
+
if hasattr(data, "revised_prompt")
|
|
84
|
+
else ""
|
|
85
|
+
),
|
|
86
|
+
}
|
|
72
87
|
}
|
|
73
88
|
]
|
|
74
89
|
span.set_attribute("llm.responses", json.dumps(response))
|
|
@@ -112,7 +127,7 @@ def async_images_generate(original_method, version, tracer):
|
|
|
112
127
|
"llm.api": APIS["IMAGES_GENERATION"]["ENDPOINT"],
|
|
113
128
|
"llm.model": kwargs.get("model"),
|
|
114
129
|
"llm.stream": kwargs.get("stream"),
|
|
115
|
-
"llm.prompts": json.dumps([kwargs.get("prompt", [])]),
|
|
130
|
+
"llm.prompts": json.dumps([{"role": "user", "content": kwargs.get("prompt", [])}]),
|
|
116
131
|
**(extra_attributes if extra_attributes is not None else {}),
|
|
117
132
|
}
|
|
118
133
|
|
|
@@ -136,12 +151,15 @@ def async_images_generate(original_method, version, tracer):
|
|
|
136
151
|
)
|
|
137
152
|
response = [
|
|
138
153
|
{
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
data.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
"role": "assistant",
|
|
155
|
+
"content": {
|
|
156
|
+
"url": data.url if hasattr(data, "url") else "",
|
|
157
|
+
"revised_prompt": (
|
|
158
|
+
data.revised_prompt
|
|
159
|
+
if hasattr(data, "revised_prompt")
|
|
160
|
+
else ""
|
|
161
|
+
),
|
|
162
|
+
}
|
|
145
163
|
}
|
|
146
164
|
]
|
|
147
165
|
span.set_attribute("llm.responses", json.dumps(response))
|
|
@@ -230,7 +248,8 @@ def chat_completions_create(original_method, version, tracer):
|
|
|
230
248
|
if kwargs.get("user") is not None:
|
|
231
249
|
attributes.llm_user = kwargs.get("user")
|
|
232
250
|
if kwargs.get("functions") is not None:
|
|
233
|
-
|
|
251
|
+
for function in kwargs.get("functions"):
|
|
252
|
+
tools.append(json.dumps({"type": "function", "function": function}))
|
|
234
253
|
if kwargs.get("tools") is not None:
|
|
235
254
|
tools.append(json.dumps(kwargs.get("tools")))
|
|
236
255
|
if len(tools) > 0:
|
|
@@ -253,25 +272,22 @@ def chat_completions_create(original_method, version, tracer):
|
|
|
253
272
|
if hasattr(result, "choices") and result.choices is not None:
|
|
254
273
|
responses = [
|
|
255
274
|
{
|
|
256
|
-
"
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
"content_filter_results"
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
for choice in result.choices
|
|
275
|
+
"role": (
|
|
276
|
+
choice.message.role
|
|
277
|
+
if choice.message and choice.message.role
|
|
278
|
+
else "assistant"
|
|
279
|
+
),
|
|
280
|
+
"content": extract_content(choice),
|
|
281
|
+
**(
|
|
282
|
+
{
|
|
283
|
+
"content_filter_results": choice[
|
|
284
|
+
"content_filter_results"
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
if "content_filter_results" in choice
|
|
288
|
+
else {}
|
|
289
|
+
),
|
|
290
|
+
} for choice in result.choices
|
|
275
291
|
]
|
|
276
292
|
span.set_attribute("llm.responses", json.dumps(responses))
|
|
277
293
|
else:
|
|
@@ -348,7 +364,7 @@ def chat_completions_create(original_method, version, tracer):
|
|
|
348
364
|
for choice in chunk.choices:
|
|
349
365
|
if (
|
|
350
366
|
choice.delta
|
|
351
|
-
and choice.delta.function_call
|
|
367
|
+
and choice.delta.function_call is not None
|
|
352
368
|
and choice.delta.function_call.arguments is not None
|
|
353
369
|
):
|
|
354
370
|
token_counts = estimate_tokens(
|
|
@@ -357,10 +373,20 @@ def chat_completions_create(original_method, version, tracer):
|
|
|
357
373
|
completion_tokens += token_counts
|
|
358
374
|
content = [choice.delta.function_call.arguments]
|
|
359
375
|
elif tool_calls:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
376
|
+
for choice in chunk.choices:
|
|
377
|
+
tool_call = ""
|
|
378
|
+
if (choice.delta and choice.delta.tool_calls is not None):
|
|
379
|
+
toolcalls = choice.delta.tool_calls
|
|
380
|
+
content = []
|
|
381
|
+
for tool_call in toolcalls:
|
|
382
|
+
if tool_call and tool_call.function is not None and tool_call.function.arguments is not None:
|
|
383
|
+
token_counts = estimate_tokens(
|
|
384
|
+
tool_call.function.arguments
|
|
385
|
+
)
|
|
386
|
+
completion_tokens += token_counts
|
|
387
|
+
content = content + [tool_call.function.arguments]
|
|
388
|
+
else:
|
|
389
|
+
content = content + []
|
|
364
390
|
else:
|
|
365
391
|
content = []
|
|
366
392
|
span.add_event(
|
|
@@ -393,10 +419,8 @@ def chat_completions_create(original_method, version, tracer):
|
|
|
393
419
|
json.dumps(
|
|
394
420
|
[
|
|
395
421
|
{
|
|
396
|
-
"
|
|
397
|
-
|
|
398
|
-
"content": "".join(result_content),
|
|
399
|
-
}
|
|
422
|
+
"role": "assistant",
|
|
423
|
+
"content": "".join(result_content),
|
|
400
424
|
}
|
|
401
425
|
]
|
|
402
426
|
),
|
|
@@ -477,7 +501,8 @@ def async_chat_completions_create(original_method, version, tracer):
|
|
|
477
501
|
if kwargs.get("user") is not None:
|
|
478
502
|
attributes.llm_user = kwargs.get("user")
|
|
479
503
|
if kwargs.get("functions") is not None:
|
|
480
|
-
|
|
504
|
+
for function in kwargs.get("functions"):
|
|
505
|
+
tools.append(json.dumps({"type": "function", "function": function}))
|
|
481
506
|
if kwargs.get("tools") is not None:
|
|
482
507
|
tools.append(json.dumps(kwargs.get("tools")))
|
|
483
508
|
if len(tools) > 0:
|
|
@@ -500,25 +525,22 @@ def async_chat_completions_create(original_method, version, tracer):
|
|
|
500
525
|
if hasattr(result, "choices") and result.choices is not None:
|
|
501
526
|
responses = [
|
|
502
527
|
{
|
|
503
|
-
"
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
"content_filter_results"
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
for choice in result.choices
|
|
528
|
+
"role": (
|
|
529
|
+
choice.message.role
|
|
530
|
+
if choice.message and choice.message.role
|
|
531
|
+
else "assistant"
|
|
532
|
+
),
|
|
533
|
+
"content": extract_content(choice),
|
|
534
|
+
**(
|
|
535
|
+
{
|
|
536
|
+
"content_filter_results": choice[
|
|
537
|
+
"content_filter_results"
|
|
538
|
+
]
|
|
539
|
+
}
|
|
540
|
+
if "content_filter_results" in choice
|
|
541
|
+
else {}
|
|
542
|
+
),
|
|
543
|
+
} for choice in result.choices
|
|
522
544
|
]
|
|
523
545
|
span.set_attribute("llm.responses", json.dumps(responses))
|
|
524
546
|
else:
|
|
@@ -604,10 +626,20 @@ def async_chat_completions_create(original_method, version, tracer):
|
|
|
604
626
|
completion_tokens += token_counts
|
|
605
627
|
content = [choice.delta.function_call.arguments]
|
|
606
628
|
elif tool_calls:
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
629
|
+
for choice in chunk.choices:
|
|
630
|
+
tool_call = ""
|
|
631
|
+
if (choice.delta and choice.delta.tool_calls is not None):
|
|
632
|
+
toolcalls = choice.delta.tool_calls
|
|
633
|
+
content = []
|
|
634
|
+
for tool_call in toolcalls:
|
|
635
|
+
if tool_call and tool_call.function is not None and tool_call.function.arguments is not None:
|
|
636
|
+
token_counts = estimate_tokens(
|
|
637
|
+
tool_call.function.arguments
|
|
638
|
+
)
|
|
639
|
+
completion_tokens += token_counts
|
|
640
|
+
content = content + [tool_call.function.arguments]
|
|
641
|
+
else:
|
|
642
|
+
content = content + []
|
|
611
643
|
else:
|
|
612
644
|
content = []
|
|
613
645
|
span.add_event(
|
|
@@ -640,10 +672,8 @@ def async_chat_completions_create(original_method, version, tracer):
|
|
|
640
672
|
json.dumps(
|
|
641
673
|
[
|
|
642
674
|
{
|
|
643
|
-
"
|
|
644
|
-
|
|
645
|
-
"content": "".join(result_content),
|
|
646
|
-
}
|
|
675
|
+
"role": "assistant",
|
|
676
|
+
"content": "".join(result_content),
|
|
647
677
|
}
|
|
648
678
|
]
|
|
649
679
|
),
|
|
@@ -680,9 +710,13 @@ def embeddings_create(original_method, version, tracer):
|
|
|
680
710
|
"llm.api": APIS["EMBEDDINGS_CREATE"]["ENDPOINT"],
|
|
681
711
|
"llm.model": kwargs.get("model"),
|
|
682
712
|
"llm.prompts": "",
|
|
713
|
+
"llm.embedding_inputs": json.dumps([kwargs.get("input", "")]),
|
|
683
714
|
**(extra_attributes if extra_attributes is not None else {}),
|
|
684
715
|
}
|
|
685
716
|
|
|
717
|
+
if kwargs.get("encoding_format") is not None:
|
|
718
|
+
span_attributes["llm.encoding_format"] = json.dumps([kwargs.get("encoding_format")])
|
|
719
|
+
|
|
686
720
|
attributes = LLMSpanAttributes(**span_attributes)
|
|
687
721
|
kwargs.get("encoding_format")
|
|
688
722
|
|
|
@@ -742,7 +776,7 @@ def async_embeddings_create(original_method, version, tracer):
|
|
|
742
776
|
"url.full": base_url,
|
|
743
777
|
"llm.api": APIS["EMBEDDINGS_CREATE"]["ENDPOINT"],
|
|
744
778
|
"llm.model": kwargs.get("model"),
|
|
745
|
-
"llm.prompts": "",
|
|
779
|
+
"llm.prompts": json.dumps([{"role": "user", "content": kwargs.get("input", "")}]),
|
|
746
780
|
**(extra_attributes if extra_attributes is not None else {}),
|
|
747
781
|
}
|
|
748
782
|
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
3
15
|
"""
|
|
4
16
|
|
|
5
17
|
import importlib.metadata
|
|
18
|
+
import logging
|
|
6
19
|
from typing import Collection
|
|
7
20
|
|
|
8
21
|
import pinecone
|
|
@@ -14,8 +27,6 @@ from wrapt import wrap_function_wrapper
|
|
|
14
27
|
from langtrace_python_sdk.constants.instrumentation.pinecone import APIS
|
|
15
28
|
from langtrace_python_sdk.instrumentation.pinecone.patch import generic_patch
|
|
16
29
|
|
|
17
|
-
import logging
|
|
18
|
-
|
|
19
30
|
logging.basicConfig(level=logging.FATAL)
|
|
20
31
|
|
|
21
32
|
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Copyright (c) 2024 Scale3 Labs
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
"""
|
|
3
16
|
|
|
4
17
|
from langtrace.trace_attributes import DatabaseSpanAttributes
|
|
5
18
|
from opentelemetry import baggage
|
|
@@ -42,12 +55,12 @@ def generic_patch(original_method, method, version, tracer):
|
|
|
42
55
|
result = original_method(instance, *args, **kwargs)
|
|
43
56
|
span.set_status(StatusCode.OK)
|
|
44
57
|
return result
|
|
45
|
-
except Exception as
|
|
58
|
+
except Exception as err:
|
|
46
59
|
# Record the exception in the span
|
|
47
|
-
span.record_exception(
|
|
60
|
+
span.record_exception(err)
|
|
48
61
|
|
|
49
62
|
# Set the span status to indicate an error
|
|
50
|
-
span.set_status(Status(StatusCode.ERROR, str(
|
|
63
|
+
span.set_status(Status(StatusCode.ERROR, str(err)))
|
|
51
64
|
|
|
52
65
|
# Reraise the exception to ensure it's not swallowed
|
|
53
66
|
raise
|