langtrace-python-sdk 3.8.8__py3-none-any.whl → 3.8.10__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.
@@ -0,0 +1,8 @@
1
+ from .basic import execute_query
2
+ from langtrace_python_sdk import with_langtrace_root_span
3
+
4
+
5
+ class Neo4jRunner:
6
+ @with_langtrace_root_span("Neo4jRunner")
7
+ def run(self):
8
+ execute_query()
@@ -0,0 +1,26 @@
1
+ import os
2
+ from langtrace_python_sdk import langtrace
3
+ from neo4j import GraphDatabase
4
+
5
+ langtrace.init()
6
+
7
+ def execute_query():
8
+ driver = GraphDatabase.driver(
9
+ os.getenv("NEO4J_URI"),
10
+ auth=(os.getenv("NEO4J_USERNAME"), os.getenv("NEO4J_PASSWORD"))
11
+ )
12
+
13
+ records, summary, keys = driver.execute_query(
14
+ "MATCH (p:Person {age: $age}) RETURN p.name AS name",
15
+ age=42,
16
+ database_=os.getenv("NEO4J_DATABASE"),
17
+ )
18
+
19
+ # Loop through results and do something with them
20
+ for person in records:
21
+ print(person)
22
+ # Summary information
23
+ print("The query `{query}` returned {records_count} records in {time} ms.".format(
24
+ query=summary.query, records_count=len(records),
25
+ time=summary.result_available_after,
26
+ ))
@@ -0,0 +1,9 @@
1
+ import asyncio
2
+ from .basic import search
3
+ from langtrace_python_sdk import with_langtrace_root_span
4
+
5
+
6
+ class Neo4jGraphRagRunner:
7
+ @with_langtrace_root_span("Neo4jGraphRagRunner")
8
+ def run(self):
9
+ asyncio.run(search())
@@ -0,0 +1,52 @@
1
+ import os
2
+ from langtrace_python_sdk import langtrace
3
+ from langtrace_python_sdk.utils.with_root_span import with_langtrace_root_span
4
+ from neo4j import GraphDatabase
5
+ from neo4j_graphrag.generation import GraphRAG
6
+ from neo4j_graphrag.indexes import create_vector_index
7
+ from neo4j_graphrag.llm import OpenAILLM as LLM
8
+ from neo4j_graphrag.embeddings import OpenAIEmbeddings as Embeddings
9
+ from neo4j_graphrag.retrievers import VectorRetriever
10
+ from neo4j_graphrag.experimental.pipeline.kg_builder import SimpleKGPipeline
11
+
12
+ langtrace.init()
13
+
14
+ neo4j_driver = GraphDatabase.driver(os.getenv("NEO4J_URI"), auth=(os.getenv("NEO4J_USERNAME"), os.getenv("NEO4J_PASSWORD")))
15
+
16
+ ex_llm=LLM(
17
+ model_name="gpt-4o-mini",
18
+ model_params={
19
+ "response_format": {"type": "json_object"},
20
+ "temperature": 0
21
+ })
22
+
23
+ embedder = Embeddings()
24
+
25
+ @with_langtrace_root_span("run_neo_rag")
26
+ async def search():
27
+ # 1. Build KG and Store in Neo4j Database
28
+ kg_builder_pdf = SimpleKGPipeline(
29
+ llm=ex_llm,
30
+ driver=neo4j_driver,
31
+ embedder=embedder,
32
+ from_pdf=True
33
+ )
34
+ await kg_builder_pdf.run_async(file_path='src/examples/neo4j_graphrag_example/data/abramov.pdf')
35
+
36
+ create_vector_index(neo4j_driver, name="text_embeddings", label="Chunk",
37
+ embedding_property="embedding", dimensions=1536, similarity_fn="cosine")
38
+
39
+ # 2. KG Retriever
40
+ vector_retriever = VectorRetriever(
41
+ neo4j_driver,
42
+ index_name="text_embeddings",
43
+ embedder=embedder
44
+ )
45
+
46
+ # 3. GraphRAG Class
47
+ llm = LLM(model_name="gpt-4o")
48
+ rag = GraphRAG(llm=llm, retriever=vector_retriever)
49
+
50
+ # 4. Run
51
+ response = rag.search("What did the author do in college?")
52
+ print(response.answer)
@@ -0,0 +1,36 @@
1
+ from langtrace.trace_attributes import Neo4jMethods
2
+
3
+ APIS = {
4
+ "RUN": {
5
+ "METHOD": Neo4jMethods.RUN.value,
6
+ "OPERATION": "run",
7
+ },
8
+ "BEGIN_TRANSACTION": {
9
+ "METHOD": Neo4jMethods.BEGIN_TRANSACTION.value,
10
+ "OPERATION": "begin_transaction",
11
+ },
12
+ "READ_TRANSACTION": {
13
+ "METHOD": Neo4jMethods.READ_TRANSACTION.value,
14
+ "OPERATION": "read_transaction",
15
+ },
16
+ "WRITE_TRANSACTION": {
17
+ "METHOD": Neo4jMethods.WRITE_TRANSACTION.value,
18
+ "OPERATION": "write_transaction",
19
+ },
20
+ "EXECUTE_READ": {
21
+ "METHOD": Neo4jMethods.EXECUTE_READ.value,
22
+ "OPERATION": "execute_read",
23
+ },
24
+ "EXECUTE_WRITE": {
25
+ "METHOD": Neo4jMethods.EXECUTE_WRITE.value,
26
+ "OPERATION": "execute_write",
27
+ },
28
+ "EXECUTE_QUERY": {
29
+ "METHOD": Neo4jMethods.EXECUTE_QUERY.value,
30
+ "OPERATION": "execute_query",
31
+ },
32
+ "TX_RUN": {
33
+ "METHOD": Neo4jMethods.TX_RUN.value,
34
+ "OPERATION": "tx_run",
35
+ },
36
+ }
@@ -22,6 +22,7 @@ from .litellm import LiteLLMInstrumentation
22
22
  from .llamaindex import LlamaindexInstrumentation
23
23
  from .milvus import MilvusInstrumentation
24
24
  from .mistral import MistralInstrumentation
25
+ from .neo4j import Neo4jInstrumentation
25
26
  from .neo4j_graphrag import Neo4jGraphRAGInstrumentation
26
27
  from .ollama import OllamaInstrumentor
27
28
  from .openai import OpenAIInstrumentation
@@ -21,7 +21,7 @@ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
21
21
  from opentelemetry.trace import get_tracer
22
22
  from wrapt import wrap_function_wrapper as _W
23
23
 
24
- from .patch import patch_agent, patch_memory
24
+ from .patch import patch_agent, patch_memory, patch_team
25
25
 
26
26
 
27
27
  class AgnoInstrumentation(BaseInstrumentor):
@@ -76,6 +76,27 @@ class AgnoInstrumentation(BaseInstrumentor):
76
76
  patch_memory("AgentMemory.aupdate_summary", version, tracer),
77
77
  )
78
78
 
79
+ _W(
80
+ "agno.team.team",
81
+ "Team.run",
82
+ patch_team("Team.run", version, tracer),
83
+ )
84
+ _W(
85
+ "agno.team.team",
86
+ "Team.arun",
87
+ patch_team("Team.arun", version, tracer),
88
+ )
89
+ _W(
90
+ "agno.team.team",
91
+ "Team._run",
92
+ patch_team("Team._run", version, tracer),
93
+ )
94
+ _W(
95
+ "agno.team.team",
96
+ "Team._arun",
97
+ patch_team("Team._arun", version, tracer),
98
+ )
99
+
79
100
  except Exception:
80
101
  pass
81
102
 
@@ -26,9 +26,7 @@ from opentelemetry.trace.status import Status, StatusCode
26
26
 
27
27
  from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
28
28
  from langtrace_python_sdk.constants.instrumentation.common import (
29
- LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
30
- SERVICE_PROVIDERS,
31
- )
29
+ LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY, SERVICE_PROVIDERS)
32
30
  from langtrace_python_sdk.utils import set_span_attribute
33
31
  from langtrace_python_sdk.utils.llm import get_span_name, set_span_attributes
34
32
  from langtrace_python_sdk.utils.misc import serialize_args, serialize_kwargs
@@ -62,9 +60,9 @@ def patch_agent(operation_name, version, tracer: Tracer):
62
60
  try:
63
61
  set_span_attributes(span, attributes)
64
62
  AgnoSpanAttributes(span=span, instance=instance)
65
-
63
+
66
64
  result = wrapped(*args, **kwargs)
67
-
65
+
68
66
  span.set_status(Status(StatusCode.OK))
69
67
 
70
68
  if operation_name in ["Agent._run", "Agent._arun", "Agent.run", "Agent.arun", "Agent.print_response"]:
@@ -72,14 +70,14 @@ def patch_agent(operation_name, version, tracer: Tracer):
72
70
  if hasattr(instance, "run_response") and instance.run_response:
73
71
  if hasattr(instance.run_response, "run_id") and instance.run_response.run_id:
74
72
  set_span_attribute(span, "agno.agent.run_id", instance.run_response.run_id)
75
-
73
+
76
74
  if hasattr(instance.run_response, "created_at") and instance.run_response.created_at:
77
75
  set_span_attribute(span, "agno.agent.timestamp", instance.run_response.created_at)
78
76
 
79
77
  if hasattr(instance.run_response, "content") and instance.run_response.content:
80
78
  content = str(instance.run_response.content)
81
79
  set_span_attribute(span, "agno.agent.response_content", content)
82
-
80
+
83
81
  # Capture any tools that were used
84
82
  if hasattr(instance.run_response, "tools") and instance.run_response.tools:
85
83
  tools = instance.run_response.tools
@@ -122,7 +120,7 @@ def patch_agent(operation_name, version, tracer: Tracer):
122
120
  else:
123
121
  set_span_attribute(span, "agno.agent.token_usage.input",
124
122
  metrics['input_tokens'])
125
-
123
+
126
124
  if 'output_tokens' in metrics:
127
125
  if isinstance(metrics['output_tokens'], list) and metrics['output_tokens']:
128
126
  set_span_attribute(span, "agno.agent.token_usage.output",
@@ -130,7 +128,7 @@ def patch_agent(operation_name, version, tracer: Tracer):
130
128
  else:
131
129
  set_span_attribute(span, "agno.agent.token_usage.output",
132
130
  metrics['output_tokens'])
133
-
131
+
134
132
  if 'total_tokens' in metrics:
135
133
  if isinstance(metrics['total_tokens'], list) and metrics['total_tokens']:
136
134
  set_span_attribute(span, "agno.agent.token_usage.total",
@@ -140,21 +138,21 @@ def patch_agent(operation_name, version, tracer: Tracer):
140
138
  metrics['total_tokens'])
141
139
  except Exception as err:
142
140
  set_span_attribute(span, "agno.agent.run_response_error", str(err))
143
-
141
+
144
142
  return result
145
-
143
+
146
144
  except Exception as err:
147
145
  span.record_exception(err)
148
146
  span.set_status(Status(StatusCode.ERROR, str(err)))
149
147
  raise
150
-
148
+
151
149
  return traced_method
152
150
 
153
151
 
154
152
  def patch_memory(operation_name, version, tracer: Tracer):
155
153
  """
156
154
  Apply instrumentation patches to AgentMemory class methods.
157
-
155
+
158
156
  Args:
159
157
  operation_name: The name of the operation
160
158
  version: The version of Agno
@@ -163,7 +161,7 @@ def patch_memory(operation_name, version, tracer: Tracer):
163
161
  def traced_method(wrapped, instance, args, kwargs):
164
162
  service_provider = SERVICE_PROVIDERS.get("AGNO", "agno")
165
163
  extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
166
-
164
+
167
165
  # Collect basic span attributes
168
166
  span_attributes = {
169
167
  "langtrace.sdk.name": "langtrace-python-sdk",
@@ -180,7 +178,7 @@ def patch_memory(operation_name, version, tracer: Tracer):
180
178
  inputs["args"] = serialize_args(*args)
181
179
  if len(kwargs) > 0:
182
180
  inputs["kwargs"] = serialize_kwargs(**kwargs)
183
-
181
+
184
182
  span_attributes["agno.memory.inputs"] = json.dumps(inputs)
185
183
 
186
184
  if hasattr(instance, "messages"):
@@ -199,10 +197,10 @@ def patch_memory(operation_name, version, tracer: Tracer):
199
197
  try:
200
198
  # Set attributes
201
199
  set_span_attributes(span, attributes)
202
-
200
+
203
201
  # Execute the wrapped method
204
202
  result = wrapped(*args, **kwargs)
205
-
203
+
206
204
  # Add memory stats after operation
207
205
  if hasattr(instance, "messages"):
208
206
  set_span_attribute(span, "agno.memory.messages_count_after", len(instance.messages))
@@ -210,37 +208,153 @@ def patch_memory(operation_name, version, tracer: Tracer):
210
208
  set_span_attribute(span, "agno.memory.runs_count_after", len(instance.runs))
211
209
  if hasattr(instance, "memories") and instance.memories:
212
210
  set_span_attribute(span, "agno.memory.memories_count_after", len(instance.memories))
213
-
211
+
214
212
  # Record execution time
215
213
  set_span_attribute(span, "agno.memory.execution_time_ms", int((time.time() - start_time) * 1000))
216
-
214
+
217
215
  # Record success status
218
216
  span.set_status(Status(StatusCode.OK))
219
-
217
+
220
218
  # Add result if relevant
221
219
  if result is not None:
222
220
  set_span_attribute(span, "agno.memory.result", str(result))
223
-
221
+
224
222
  return result
225
-
223
+
226
224
  except Exception as err:
227
225
  # Record the exception
228
226
  span.record_exception(err)
229
227
  span.set_status(Status(StatusCode.ERROR, str(err)))
230
228
  raise
231
-
229
+
232
230
  return traced_method
233
231
 
234
232
 
233
+ def patch_team(operation_name, version, tracer: Tracer):
234
+ def traced_method(wrapped, instance, args, kwargs):
235
+ service_provider = SERVICE_PROVIDERS.get("AGNO", "agno")
236
+ extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
237
+
238
+ span_attributes = {
239
+ "langtrace.sdk.name": "langtrace-python-sdk",
240
+ "langtrace.service.name": service_provider,
241
+ "langtrace.service.type": "framework",
242
+ "langtrace.service.version": version,
243
+ "langtrace.version": v(LANGTRACE_SDK_NAME),
244
+ **(extra_attributes if extra_attributes is not None else {}),
245
+ }
246
+
247
+ inputs = {}
248
+ if len(args) > 0:
249
+ inputs["args"] = serialize_args(*args)
250
+ if len(kwargs) > 0:
251
+ inputs["kwargs"] = serialize_kwargs(**kwargs)
252
+ span_attributes["agno.team.inputs"] = json.dumps(inputs)
253
+ attributes = FrameworkSpanAttributes(**span_attributes)
254
+
255
+ with tracer.start_as_current_span(
256
+ get_span_name(operation_name), kind=SpanKind.CLIENT
257
+ ) as span:
258
+ try:
259
+ set_span_attributes(span, attributes)
260
+ AgnoSpanAttributes(span=span, instance=instance)
261
+
262
+ result = wrapped(*args, **kwargs)
263
+
264
+ span.set_status(Status(StatusCode.OK))
265
+
266
+ if operation_name in ["Team.run", "Team.arun", "Team._run", "Team._arun"]:
267
+ try:
268
+ if hasattr(instance, "run_response") and instance.run_response:
269
+ if hasattr(instance.run_response, "run_id") and instance.run_response.run_id:
270
+ set_span_attribute(span, "agno.team.run_id", instance.run_response.run_id)
271
+
272
+ if hasattr(instance.run_response, "created_at") and instance.run_response.created_at:
273
+ set_span_attribute(span, "agno.team.timestamp", instance.run_response.created_at)
274
+
275
+ if hasattr(instance.run_response, "content") and instance.run_response.content:
276
+ content = str(instance.run_response.content)
277
+ set_span_attribute(span, "agno.team.response_content", content)
278
+
279
+ # Capture any tools that were used
280
+ if hasattr(instance.run_response, "tools") and instance.run_response.tools:
281
+ tools = instance.run_response.tools
282
+ tool_summary = []
283
+ for tool in tools:
284
+ if 'tool_name' in tool:
285
+ tool_summary.append(tool['tool_name'])
286
+ elif 'function' in tool and 'name' in tool['function']:
287
+ tool_summary.append(tool['function']['name'])
288
+ set_span_attribute(span, "agno.team.tools_used", json.dumps(tool_summary))
289
+
290
+ if hasattr(instance.run_response, "metrics") and instance.run_response.metrics:
291
+ metrics = instance.run_response.metrics
292
+ for metric_name, metric_values in metrics.items():
293
+ if isinstance(metric_values, list):
294
+
295
+ if all(isinstance(v, (int, float)) for v in metric_values):
296
+ set_span_attribute(
297
+ span,
298
+ f"agno.team.metrics.{metric_name}",
299
+ sum(metric_values) / len(metric_values) if metric_values else 0
300
+ )
301
+ elif len(metric_values) > 0:
302
+ set_span_attribute(
303
+ span,
304
+ f"agno.team.metrics.{metric_name}",
305
+ str(metric_values[-1])
306
+ )
307
+ else:
308
+ set_span_attribute(
309
+ span,
310
+ f"agno.team.metrics.{metric_name}",
311
+ str(metric_values)
312
+ )
313
+
314
+ if 'input_tokens' in metrics:
315
+ if isinstance(metrics['input_tokens'], list) and metrics['input_tokens']:
316
+ set_span_attribute(span, "agno.team.token_usage.input",
317
+ sum(metrics['input_tokens']))
318
+ else:
319
+ set_span_attribute(span, "agno.team.token_usage.input",
320
+ metrics['input_tokens'])
321
+
322
+ if 'output_tokens' in metrics:
323
+ if isinstance(metrics['output_tokens'], list) and metrics['output_tokens']:
324
+ set_span_attribute(span, "agno.team.token_usage.output",
325
+ sum(metrics['output_tokens']))
326
+ else:
327
+ set_span_attribute(span, "agno.team.token_usage.output",
328
+ metrics['output_tokens'])
329
+
330
+ if 'total_tokens' in metrics:
331
+ if isinstance(metrics['total_tokens'], list) and metrics['total_tokens']:
332
+ set_span_attribute(span, "agno.team.token_usage.total",
333
+ sum(metrics['total_tokens']))
334
+ else:
335
+ set_span_attribute(span, "agno.team.token_usage.total",
336
+ metrics['total_tokens'])
337
+ except Exception as err:
338
+ set_span_attribute(span, "agno.team.run_response_error", str(err))
339
+
340
+ return result
341
+
342
+ except Exception as err:
343
+ span.record_exception(err)
344
+ span.set_status(Status(StatusCode.ERROR, str(err)))
345
+ raise
346
+
347
+ return traced_method
348
+
235
349
  class AgnoSpanAttributes:
236
350
  """
237
351
  Helper class to extract and set Agno Agent attributes on spans.
238
352
  """
239
-
353
+
240
354
  def __init__(self, span: Span, instance: Any) -> None:
241
355
  """
242
356
  Initialize with a span and Agno instance.
243
-
357
+
244
358
  Args:
245
359
  span: OpenTelemetry span to update
246
360
  instance: Agno Agent instance
@@ -248,14 +362,14 @@ class AgnoSpanAttributes:
248
362
  self.span = span
249
363
  self.instance = instance
250
364
  self.agent_data = {}
251
-
365
+
252
366
  self.run()
253
-
367
+
254
368
  def run(self) -> None:
255
369
  """Process the instance attributes and add them to the span."""
256
370
  # Collect basic agent attributes
257
371
  self.collect_agent_attributes()
258
-
372
+
259
373
  # Add attributes to span
260
374
  for key, value in self.agent_data.items():
261
375
  if value is not None:
@@ -264,68 +378,68 @@ class AgnoSpanAttributes:
264
378
  f"agno.agent.{key}",
265
379
  str(value) if not isinstance(value, (int, float, bool)) else value
266
380
  )
267
-
381
+
268
382
  def collect_agent_attributes(self) -> None:
269
383
  """Collect important attributes from the Agent instance."""
270
384
  # Extract basic agent information
271
385
  if hasattr(self.instance, "agent_id"):
272
386
  self.agent_data["id"] = self.instance.agent_id
273
-
387
+
274
388
  if hasattr(self.instance, "name"):
275
389
  self.agent_data["name"] = self.instance.name
276
-
390
+
277
391
  if hasattr(self.instance, "session_id"):
278
392
  self.agent_data["session_id"] = self.instance.session_id
279
-
393
+
280
394
  if hasattr(self.instance, "user_id"):
281
395
  self.agent_data["user_id"] = self.instance.user_id
282
-
396
+
283
397
  if hasattr(self.instance, "run_id"):
284
398
  self.agent_data["run_id"] = self.instance.run_id
285
-
286
- # Extract model information
399
+
400
+ # Extract model information
287
401
  if hasattr(self.instance, "model") and self.instance.model:
288
402
  model = self.instance.model
289
403
  model_info = {}
290
-
404
+
291
405
  if hasattr(model, "id"):
292
406
  model_info["id"] = model.id
293
-
407
+
294
408
  if hasattr(model, "name"):
295
409
  model_info["name"] = model.name
296
-
410
+
297
411
  if hasattr(model, "provider"):
298
412
  model_info["provider"] = model.provider
299
-
413
+
300
414
  # Add temperature if available
301
415
  if hasattr(model, "temperature") and model.temperature is not None:
302
416
  model_info["temperature"] = model.temperature
303
-
417
+
304
418
  # Add max_tokens if available
305
419
  if hasattr(model, "max_tokens") and model.max_tokens is not None:
306
420
  model_info["max_tokens"] = model.max_tokens
307
-
421
+
308
422
  self.agent_data["model"] = json.dumps(model_info)
309
-
423
+
310
424
  # Extract tool information
311
425
  if hasattr(self.instance, "tools") and self.instance.tools:
312
426
  tool_info = []
313
427
  for tool in self.instance.tools:
314
428
  tool_data = {}
315
-
429
+
316
430
  # Handle different types of tools
317
431
  if hasattr(tool, "name"):
318
432
  tool_data["name"] = tool.name
319
-
433
+
320
434
  # Handle DuckDuckGoTools and similar toolkits
321
435
  if hasattr(tool, "functions") and isinstance(tool.functions, dict):
322
436
  tool_data["functions"] = list(tool.functions.keys())
323
-
437
+
324
438
  elif hasattr(tool, "__name__"):
325
439
  tool_data["name"] = tool.__name__
326
440
  else:
327
441
  tool_data["name"] = str(tool)
328
-
442
+
329
443
  # Add functions if available
330
444
  if not "functions" in tool_data and hasattr(tool, "functions"):
331
445
  if callable(getattr(tool, "functions")):
@@ -336,28 +450,28 @@ class AgnoSpanAttributes:
336
450
  for f in tool_functions]
337
451
  except:
338
452
  pass
339
-
453
+
340
454
  tool_info.append(tool_data)
341
-
455
+
342
456
  self.agent_data["tools"] = json.dumps(tool_info)
343
-
457
+
344
458
  # Extract reasoning settings
345
459
  if hasattr(self.instance, "reasoning") and self.instance.reasoning:
346
460
  self.agent_data["reasoning_enabled"] = True
347
-
461
+
348
462
  if hasattr(self.instance, "reasoning_model") and self.instance.reasoning_model:
349
463
  self.agent_data["reasoning_model"] = str(self.instance.reasoning_model.id)
350
-
464
+
351
465
  if hasattr(self.instance, "reasoning_min_steps"):
352
466
  self.agent_data["reasoning_min_steps"] = self.instance.reasoning_min_steps
353
-
467
+
354
468
  if hasattr(self.instance, "reasoning_max_steps"):
355
469
  self.agent_data["reasoning_max_steps"] = self.instance.reasoning_max_steps
356
-
470
+
357
471
  # Extract knowledge settings
358
472
  if hasattr(self.instance, "knowledge") and self.instance.knowledge:
359
473
  self.agent_data["knowledge_enabled"] = True
360
-
474
+
361
475
  # Extract streaming settings
362
476
  if hasattr(self.instance, "stream"):
363
- self.agent_data["stream"] = self.instance.stream
477
+ self.agent_data["stream"] = self.instance.stream
@@ -8,7 +8,7 @@ from .patch import patch_google_genai, patch_google_genai_streaming
8
8
 
9
9
  class GoogleGenaiInstrumentation(BaseInstrumentor):
10
10
  def instrumentation_dependencies(self) -> Collection[str]:
11
- return ["google-genai >= 0.1.0", "google-generativeai < 1.0.0"]
11
+ return ["google-genai >= 0.1.0"]
12
12
 
13
13
  def _instrument(self, **kwargs):
14
14
  trace_provider = kwargs.get("tracer_provider")
@@ -0,0 +1,3 @@
1
+ from .instrumentation import Neo4jInstrumentation
2
+
3
+ __all__ = ["Neo4jInstrumentation"]
@@ -0,0 +1,51 @@
1
+ """
2
+ Copyright (c) 2025 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
+
17
+ import importlib.metadata
18
+ import logging
19
+ from typing import Collection
20
+
21
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
22
+ from opentelemetry.trace import get_tracer
23
+ from wrapt import wrap_function_wrapper
24
+
25
+ from langtrace_python_sdk.constants.instrumentation.neo4j import APIS
26
+ from langtrace_python_sdk.instrumentation.neo4j.patch import driver_patch
27
+
28
+ logging.basicConfig(level=logging.FATAL)
29
+
30
+
31
+ class Neo4jInstrumentation(BaseInstrumentor):
32
+ """
33
+ The Neo4jInstrumentation class represents the Neo4j graph database instrumentation
34
+ """
35
+
36
+ def instrumentation_dependencies(self) -> Collection[str]:
37
+ return ["neo4j >= 5.25.0"]
38
+
39
+ def _instrument(self, **kwargs):
40
+ tracer_provider = kwargs.get("tracer_provider")
41
+ tracer = get_tracer(__name__, "", tracer_provider)
42
+ version = importlib.metadata.version("neo4j")
43
+
44
+ wrap_function_wrapper(
45
+ "neo4j._sync.driver",
46
+ "Driver.execute_query",
47
+ driver_patch("EXECUTE_QUERY", version, tracer),
48
+ )
49
+
50
+ def _uninstrument(self, **kwargs):
51
+ pass
@@ -0,0 +1,180 @@
1
+ """
2
+ Copyright (c) 2025 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
+
17
+ import json
18
+
19
+ from langtrace_python_sdk.utils.llm import get_span_name
20
+ from langtrace_python_sdk.utils.silently_fail import silently_fail
21
+ from langtrace.trace_attributes import DatabaseSpanAttributes
22
+ from langtrace_python_sdk.utils import set_span_attribute
23
+ from opentelemetry import baggage, trace
24
+ from opentelemetry.trace import SpanKind
25
+ from opentelemetry.trace.status import Status, StatusCode
26
+ from opentelemetry.trace.propagation import set_span_in_context
27
+
28
+ from langtrace_python_sdk.constants.instrumentation.common import (
29
+ LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
30
+ SERVICE_PROVIDERS,
31
+ )
32
+ from langtrace_python_sdk.constants.instrumentation.neo4j import APIS
33
+ from importlib.metadata import version as v
34
+
35
+ from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
36
+
37
+
38
+ def driver_patch(operation_name, version, tracer):
39
+ def traced_method(wrapped, instance, args, kwargs):
40
+
41
+ api = APIS[operation_name]
42
+ service_provider = SERVICE_PROVIDERS.get("NEO4J", "neo4j")
43
+ extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
44
+ span_attributes = {
45
+ "langtrace.sdk.name": "langtrace-python-sdk",
46
+ "langtrace.service.name": service_provider,
47
+ "langtrace.service.type": "vectordb",
48
+ "langtrace.service.version": version,
49
+ "langtrace.version": v(LANGTRACE_SDK_NAME),
50
+ "db.system": "neo4j",
51
+ "db.operation": api["OPERATION"],
52
+ "db.query": json.dumps(args[0]) if args and len(args) > 0 else "",
53
+ **(extra_attributes if extra_attributes is not None else {}),
54
+ }
55
+
56
+ attributes = DatabaseSpanAttributes(**span_attributes)
57
+
58
+ with tracer.start_as_current_span(
59
+ name=get_span_name(api["METHOD"]),
60
+ kind=SpanKind.CLIENT,
61
+ context=set_span_in_context(trace.get_current_span()),
62
+ ) as span:
63
+ for field, value in attributes.model_dump(by_alias=True).items():
64
+ if value is not None:
65
+ span.set_attribute(field, value)
66
+
67
+ if operation_name == "EXECUTE_QUERY":
68
+ _set_execute_query_attributes(span, args, kwargs)
69
+
70
+ try:
71
+ result = wrapped(*args, **kwargs)
72
+
73
+ if isinstance(result, tuple) and len(result) == 3:
74
+ records, result_summary, keys = result
75
+ _set_result_attributes(span, records, result_summary, keys)
76
+ else:
77
+ res = json.dumps(result)
78
+ set_span_attribute(span, "neo4j.result.query_response", res)
79
+
80
+ span.set_status(StatusCode.OK)
81
+ return result
82
+ except Exception as err:
83
+ span.record_exception(err)
84
+ span.set_status(Status(StatusCode.ERROR, str(err)))
85
+ raise
86
+
87
+ return traced_method
88
+
89
+
90
+ @silently_fail
91
+ def _set_execute_query_attributes(span, args, kwargs):
92
+ query = args[0] if args else kwargs.get("query_", None)
93
+ if query:
94
+ if hasattr(query, "text"):
95
+ set_span_attribute(span, "db.query", query.text)
96
+ if hasattr(query, "metadata") and query.metadata:
97
+ set_span_attribute(span, "db.query.metadata", json.dumps(query.metadata))
98
+ if hasattr(query, "timeout") and query.timeout:
99
+ set_span_attribute(span, "db.query.timeout", query.timeout)
100
+ else:
101
+ set_span_attribute(span, "db.query", query)
102
+
103
+ parameters = kwargs.get("parameters_", None)
104
+ if parameters:
105
+ try:
106
+ set_span_attribute(span, "db.statement.parameters", json.dumps(parameters))
107
+ except (TypeError, ValueError):
108
+ pass
109
+
110
+ database = kwargs.get("database_", None)
111
+ if database:
112
+ set_span_attribute(span, "neo4j.db.name", database)
113
+
114
+ routing = kwargs.get("routing_", None)
115
+ if routing:
116
+ set_span_attribute(span, "neo4j.db.routing", str(routing))
117
+
118
+
119
+ @silently_fail
120
+ def _set_result_attributes(span, records, result_summary, keys):
121
+ """
122
+ Set attributes related to the query result and summary
123
+ """
124
+ if records is not None:
125
+ record_count = len(records)
126
+ set_span_attribute(span, "neo4j.result.record_count", record_count)
127
+ if record_count > 0:
128
+ set_span_attribute(span, "neo4j.result.records", json.dumps(records))
129
+
130
+ if keys is not None:
131
+ set_span_attribute(span, "neo4j.result.keys", json.dumps(keys))
132
+
133
+ if result_summary:
134
+ if hasattr(result_summary, "database") and result_summary.database:
135
+ set_span_attribute(span, "neo4j.db.name", result_summary.database)
136
+
137
+ if hasattr(result_summary, "query_type") and result_summary.query_type:
138
+ set_span_attribute(span, "neo4j.result.query_type", result_summary.query_type)
139
+
140
+ if hasattr(result_summary, "parameters") and result_summary.parameters:
141
+ try:
142
+ set_span_attribute(span, "neo4j.result.parameters", json.dumps(result_summary.parameters))
143
+ except (TypeError, ValueError):
144
+ pass
145
+
146
+ if hasattr(result_summary, "result_available_after") and result_summary.result_available_after is not None:
147
+ set_span_attribute(span, "neo4j.result.available_after_ms", result_summary.result_available_after)
148
+
149
+ if hasattr(result_summary, "result_consumed_after") and result_summary.result_consumed_after is not None:
150
+ set_span_attribute(span, "neo4j.result.consumed_after_ms", result_summary.result_consumed_after)
151
+
152
+ if hasattr(result_summary, "counters") and result_summary.counters:
153
+ counters = result_summary.counters
154
+ if hasattr(counters, "nodes_created") and counters.nodes_created:
155
+ set_span_attribute(span, "neo4j.result.nodes_created", counters.nodes_created)
156
+
157
+ if hasattr(counters, "nodes_deleted") and counters.nodes_deleted:
158
+ set_span_attribute(span, "neo4j.result.nodes_deleted", counters.nodes_deleted)
159
+
160
+ if hasattr(counters, "relationships_created") and counters.relationships_created:
161
+ set_span_attribute(span, "neo4j.result.relationships_created", counters.relationships_created)
162
+
163
+ if hasattr(counters, "relationships_deleted") and counters.relationships_deleted:
164
+ set_span_attribute(span, "neo4j.result.relationships_deleted", counters.relationships_deleted)
165
+
166
+ if hasattr(counters, "properties_set") and counters.properties_set:
167
+ set_span_attribute(span, "neo4j.result.properties_set", counters.properties_set)
168
+
169
+ if hasattr(result_summary, "plan") and result_summary.plan:
170
+ try:
171
+ set_span_attribute(span, "neo4j.result.plan", json.dumps(result_summary.plan))
172
+ except (TypeError, ValueError):
173
+ pass
174
+
175
+ if hasattr(result_summary, "notifications") and result_summary.notifications:
176
+ try:
177
+ set_span_attribute(span, "neo4j.result.notification_count", len(result_summary.notifications))
178
+ set_span_attribute(span, "neo4j.result.notifications", json.dumps(result_summary.notifications))
179
+ except (AttributeError, TypeError):
180
+ pass
@@ -26,9 +26,7 @@ from opentelemetry.trace.status import Status, StatusCode
26
26
 
27
27
  from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
28
28
  from langtrace_python_sdk.constants.instrumentation.common import (
29
- LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
30
- SERVICE_PROVIDERS,
31
- )
29
+ LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY, SERVICE_PROVIDERS)
32
30
  from langtrace_python_sdk.constants.instrumentation.weaviate import APIS
33
31
  from langtrace_python_sdk.utils.llm import get_span_name
34
32
  from langtrace_python_sdk.utils.misc import extract_input_params, to_iso_format
@@ -53,6 +51,8 @@ def extract_inputs(args, kwargs):
53
51
  for k, v in kwargs.items()
54
52
  if k not in ["properties", "fusion_type", "filters"]
55
53
  }
54
+ # don't include vector in kwargs_without_properties
55
+ kwargs_without_properties.pop("vector", None)
56
56
  extracted_params.update(extract_input_params(args, kwargs_without_properties))
57
57
  if kwargs.get("filters", None):
58
58
  extracted_params["filters"] = str(kwargs["filters"])
@@ -109,7 +109,7 @@ def get_response_object_attributes(response_object):
109
109
  **{k: convert_value(v) for k, v in response_object.properties.items()},
110
110
  "uuid": str(response_object.uuid) if hasattr(response_object, "uuid") else None,
111
111
  "collection": getattr(response_object, "collection", None),
112
- "vector": getattr(response_object, "vector", None),
112
+ # "vector": getattr(response_object, "vector", None),
113
113
  "references": getattr(response_object, "references", None),
114
114
  "metadata": (
115
115
  extract_metadata(response_object.metadata)
@@ -47,9 +47,9 @@ from langtrace_python_sdk.instrumentation import (
47
47
  CrewaiToolsInstrumentation, DspyInstrumentation, EmbedchainInstrumentation,
48
48
  GeminiInstrumentation, GoogleGenaiInstrumentation, GraphlitInstrumentation,
49
49
  GroqInstrumentation, LangchainCommunityInstrumentation,
50
- LangchainCoreInstrumentation, LangchainInstrumentation,
51
- LanggraphInstrumentation, LiteLLMInstrumentation, LlamaindexInstrumentation,
52
- MilvusInstrumentation, MistralInstrumentation, Neo4jGraphRAGInstrumentation,
50
+ LangchainCoreInstrumentation, LangchainInstrumentation, LanggraphInstrumentation,
51
+ LiteLLMInstrumentation, LlamaindexInstrumentation, MilvusInstrumentation,
52
+ MistralInstrumentation, Neo4jInstrumentation, Neo4jGraphRAGInstrumentation,
53
53
  OllamaInstrumentor, OpenAIAgentsInstrumentation, OpenAIInstrumentation,
54
54
  PhiDataInstrumentation, PineconeInstrumentation, PyMongoInstrumentation,
55
55
  QdrantInstrumentation, VertexAIInstrumentation, WeaviateInstrumentation)
@@ -284,6 +284,7 @@ def init(
284
284
  "phidata": PhiDataInstrumentation(),
285
285
  "agno": AgnoInstrumentation(),
286
286
  "mistralai": MistralInstrumentation(),
287
+ "neo4j": Neo4jInstrumentation(),
287
288
  "neo4j-graphrag": Neo4jGraphRAGInstrumentation(),
288
289
  "boto3": AWSBedrockInstrumentation(),
289
290
  "autogen": AutogenInstrumentation(),
@@ -14,25 +14,24 @@ See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  """
16
16
 
17
+ import json
18
+ import os
17
19
  from typing import Any, Dict, Union
18
- from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
19
- from langtrace_python_sdk.utils import set_span_attribute
20
- from langtrace_python_sdk.types import NOT_GIVEN
21
- from tiktoken import get_encoding, list_encoding_names
22
20
 
23
- from langtrace_python_sdk.constants.instrumentation.common import (
24
- LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
25
- TIKTOKEN_MODEL_MAPPING,
26
- )
27
- from langtrace_python_sdk.constants.instrumentation.openai import OPENAI_COST_TABLE
28
- from langtrace.trace_attributes import SpanAttributes
29
21
  from importlib_metadata import version as v
30
- import json
22
+ from langtrace.trace_attributes import SpanAttributes
31
23
  from opentelemetry import baggage
32
24
  from opentelemetry.trace import Span
33
25
  from opentelemetry.trace.status import StatusCode
26
+ from tiktoken import get_encoding, list_encoding_names
34
27
 
35
- import os
28
+ from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
29
+ from langtrace_python_sdk.constants.instrumentation.common import (
30
+ LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY, TIKTOKEN_MODEL_MAPPING)
31
+ from langtrace_python_sdk.constants.instrumentation.openai import \
32
+ OPENAI_COST_TABLE
33
+ from langtrace_python_sdk.types import NOT_GIVEN
34
+ from langtrace_python_sdk.utils import set_span_attribute
36
35
 
37
36
 
38
37
  def get_span_name(operation_name):
@@ -437,7 +436,6 @@ class StreamWrapper:
437
436
  "".join(self.result_content), response_model
438
437
  )
439
438
  if self._span_started:
440
- print("SPAAN", self.span)
441
439
  set_span_attribute(
442
440
  self.span,
443
441
  SpanAttributes.LLM_RESPONSE_MODEL,
@@ -1 +1 @@
1
- __version__ = "3.8.8"
1
+ __version__ = "3.8.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langtrace-python-sdk
3
- Version: 3.8.8
3
+ Version: 3.8.10
4
4
  Summary: Python SDK for LangTrace
5
5
  Project-URL: Homepage, https://github.com/Scale3-Labs/langtrace-python-sdk
6
6
  Author-email: Scale3 Labs <engineering@scale3labs.com>
@@ -23,7 +23,7 @@ Requires-Dist: sentry-sdk>=2.14.0
23
23
  Requires-Dist: setuptools
24
24
  Requires-Dist: sqlalchemy
25
25
  Requires-Dist: tiktoken>=0.1.1
26
- Requires-Dist: trace-attributes==7.2.0
26
+ Requires-Dist: trace-attributes==7.2.1
27
27
  Requires-Dist: transformers>=4.11.3
28
28
  Requires-Dist: ujson>=5.10.0
29
29
  Provides-Extra: dev
@@ -83,6 +83,11 @@ examples/mistral_example/complete.py,sha256=Ydf5iOCGM2tySSd5vzGvNh3Qz39aTpxcCItB
83
83
  examples/mistral_example/complete_async.py,sha256=-SVOLNLNi5JL3o4obBsCXKOt8A6b61j3otbrrYPOOtM,586
84
84
  examples/mistral_example/embeddings.py,sha256=LKq_k3Y-TS2SCkyFKw2tLiYreVRHqlY6z0Gfh1y_7u0,468
85
85
  examples/mongo_vector_search_example/main.py,sha256=6bHOxR3LfAZwmGmv74jgNCciATS5h5e-Tb5z0cD0z3Q,1542
86
+ examples/neo4j_example/__init__.py,sha256=YG7-_cQnXt-fJQtH2bJu_uSNyVCmYyUevU4H-GML_Sk,200
87
+ examples/neo4j_example/basic.py,sha256=xw5fNi5y-U5wzrVIsnvbKBZDURUzoYriawu6nyEXi3o,780
88
+ examples/neo4j_graphrag_example/__init__.py,sha256=YCXutcM3otTKEff1S3qTciFBxOMrQw7mQ4WGfJ7-mU8,230
89
+ examples/neo4j_graphrag_example/basic.py,sha256=uYf4O8bT3GkU5Qa-tluEr9sYTm5gjdzHAKf-C8bi5GY,1727
90
+ examples/neo4j_graphrag_example/data/abramov.pdf,sha256=Fm93bGdz74PJel-Dw_wZeuqqedloTTZiOakIWLzYDPA,46933
86
91
  examples/ollama_example/__init__.py,sha256=qOx0jGCPuSpRCPiqtDVm7F0z8hIZ8C75hDZ_C8Apz-s,399
87
92
  examples/ollama_example/basic.py,sha256=EPbsigOF4xBDBgLgAD0EzPo737ycVm7aXZr7F5Xt-A4,1062
88
93
  examples/openai_example/__init__.py,sha256=6faH7wTegSozKmS89sd1Tgv8AcEH0GfKkC7YaBWA8tg,849
@@ -115,8 +120,8 @@ examples/vertexai_example/main.py,sha256=gndId5X5ksD-ycxnAWMdEqIDbLc3kz5Vt8vm4YP
115
120
  examples/weaviate_example/__init__.py,sha256=8JMDBsRSEV10HfTd-YC7xb4txBjD3la56snk-Bbg2Kw,618
116
121
  examples/weaviate_example/query_text.py,sha256=wPHQTc_58kPoKTZMygVjTj-2ZcdrIuaausJfMxNQnQc,127162
117
122
  langtrace_python_sdk/__init__.py,sha256=VZM6i71NR7pBQK6XvJWRelknuTYUhqwqE7PlicKa5Wg,1166
118
- langtrace_python_sdk/langtrace.py,sha256=4nhcy9_T3h4m5T5Blyrvs0BJcKzPWMtkIyEDSbba8P8,13879
119
- langtrace_python_sdk/version.py,sha256=3SjfTmtUQqjDdaQC3uiCoISksstrQ1Sqj4ASUtoUrzs,22
123
+ langtrace_python_sdk/langtrace.py,sha256=P7aHGunNP8YQqd2glsVLXhSe4QDeAarfG2eCV9hhAm4,13944
124
+ langtrace_python_sdk/version.py,sha256=Sz-5SfPXsiZbJO0dp0pVWeIm92HyINLVnoY9zyB3FQI,23
120
125
  langtrace_python_sdk/constants/__init__.py,sha256=3CNYkWMdd1DrkGqzLUgNZXjdAlM6UFMlf_F-odAToyc,146
121
126
  langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=EVCrouYCpY98f0KSaKr4PzNxPULTZZO6dSA_crEOyJU,106
122
127
  langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -131,6 +136,7 @@ langtrace_python_sdk/constants/instrumentation/groq.py,sha256=VFXmIl4aqGY_fS0PAm
131
136
  langtrace_python_sdk/constants/instrumentation/litellm.py,sha256=bMAlpY2scFe6Lql0Nl7euGNSO9QEV5Uzne12hnw3mSE,449
132
137
  langtrace_python_sdk/constants/instrumentation/milvus.py,sha256=lnl7RtV2Wc66mEmtVMjV5eWalt-caH4-sQEHpN1LmEE,1029
133
138
  langtrace_python_sdk/constants/instrumentation/mistral.py,sha256=9PlmcC5P5_BHJ-zsX1xekht6rSm7arTin58HAfdYvLk,730
139
+ langtrace_python_sdk/constants/instrumentation/neo4j.py,sha256=-coUUCiroN2shr_C-HcWPYPmEcjIz1CQpaXtZo2uVFU,1002
134
140
  langtrace_python_sdk/constants/instrumentation/ollama.py,sha256=H_-S0xjqRsi5qSp7mAlK7Y9NlQ3BqOkG6ASogqqgdJY,212
135
141
  langtrace_python_sdk/constants/instrumentation/openai.py,sha256=uEOH5UXapU2DSf2AdgXTRhhJEHGWXUNFkUGD5QafflM,1164
136
142
  langtrace_python_sdk/constants/instrumentation/pinecone.py,sha256=0TityERbGWaHGSN8-vyYZtYCjVj8fQOKae8lng0O0Bk,478
@@ -141,10 +147,10 @@ langtrace_python_sdk/constants/instrumentation/weaviate.py,sha256=gtv-JBxvNGClEM
141
147
  langtrace_python_sdk/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
148
  langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=ckd8dMmY6h2oxE04p1JFLwUB5PSJX_Cy4eDFEM6aj4Y,6605
143
149
  langtrace_python_sdk/extensions/langtrace_filesystem.py,sha256=34fZutG28EJ66l67OvTGsydAH3ZpXgikdE7hVLqBpG4,7863
144
- langtrace_python_sdk/instrumentation/__init__.py,sha256=lw53EsTTtOK-dMhImudipmbVhZqORylt4hO5A7Mv8Uo,2652
150
+ langtrace_python_sdk/instrumentation/__init__.py,sha256=sUVSZtidQev87AspZmWK4M8J51mBnJXXNDwfBsl_Dcs,2692
145
151
  langtrace_python_sdk/instrumentation/agno/__init__.py,sha256=95fn4oA-CHB0mxc6KnVB20KSbXGl_ZZr9n99EEaXzrY,91
146
- langtrace_python_sdk/instrumentation/agno/instrumentation.py,sha256=XUnfvqpp13IgdF03xGKasq7kGjeaN1sXLIwCf-Nt_Nc,2667
147
- langtrace_python_sdk/instrumentation/agno/patch.py,sha256=qCUxCkzU9cYu_d8BzLgj_Ss97qib07tRVYpYDiNnNMs,16876
152
+ langtrace_python_sdk/instrumentation/agno/instrumentation.py,sha256=DWOIEl9Q4IhCFgFQPW3pILdVq_C0RJiaGm_diZ73XJU,3284
153
+ langtrace_python_sdk/instrumentation/agno/patch.py,sha256=wHMDNiH-XOUTnqC6HKGGbYOp04R8DG2xJqm9Ex_h9AE,22868
148
154
  langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
149
155
  langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=ndXdruI0BG7n75rsuEpKjfzePxrZxg40gZ39ONmD_v4,1845
150
156
  langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=ztPN4VZujoxYOKhTbFnup7Ibms9NAzYCPAJY43NUgKw,4935
@@ -185,7 +191,7 @@ langtrace_python_sdk/instrumentation/gemini/__init__.py,sha256=ilWmKA4Li-g3DX6R1
185
191
  langtrace_python_sdk/instrumentation/gemini/instrumentation.py,sha256=eGWr2dy1f_9TVZiXSH_MlNQINyS4I28EsOTKREdMVio,1304
186
192
  langtrace_python_sdk/instrumentation/gemini/patch.py,sha256=PG5E5v253x2ufQ81-aUUFzDRYq-DDhiqwmNoplHPjsM,6261
187
193
  langtrace_python_sdk/instrumentation/google_genai/__init__.py,sha256=nQ2kSsUDpLGZ_kz2QGddDwnawL9juVA7pW4G-BOe5VI,98
188
- langtrace_python_sdk/instrumentation/google_genai/instrumentation.py,sha256=oqKDhVcRRHhD5tK3adAIQo9Bpe7CA-k33gla1IymwXU,1080
194
+ langtrace_python_sdk/instrumentation/google_genai/instrumentation.py,sha256=rSB3nOXXe4gMVPWMGPnIHvWjqyPeRvifxOI62ulJ7uY,1049
189
195
  langtrace_python_sdk/instrumentation/google_genai/patch.py,sha256=X0TWY1D4XHweaNu70PlXBDzKEaHIibLpkJiIsp4jF6A,4115
190
196
  langtrace_python_sdk/instrumentation/graphlit/__init__.py,sha256=mkUPwozR-I-D5ZrumJs1gS7sSouY0UN68Ne9LiNEBTs,92
191
197
  langtrace_python_sdk/instrumentation/graphlit/instrumentation.py,sha256=V9GRZ6cj2lt20xCVfL55lGU4p0HlZxAYUqwpWogXDtY,2074
@@ -218,6 +224,9 @@ langtrace_python_sdk/instrumentation/milvus/patch.py,sha256=0yY5aQz0x7hpQZ8U-0qf
218
224
  langtrace_python_sdk/instrumentation/mistral/__init__.py,sha256=mkGALBQvq0jSfwDl6TU09SFwnVs6O4zkUi-yVmd3SNg,90
219
225
  langtrace_python_sdk/instrumentation/mistral/instrumentation.py,sha256=qtCkHCSOaiicUChbmTID4lcK1rbeW8oRSbpda2ogbgM,2328
220
226
  langtrace_python_sdk/instrumentation/mistral/patch.py,sha256=5EzqMeIEcMUH8P-l9-ijpRNWSc6mYwe9Gz0VY4PLrS0,6559
227
+ langtrace_python_sdk/instrumentation/neo4j/__init__.py,sha256=6pG7SKOSKENaFEsstMJ4ZUH9wUP53JdQKdjHzJ4Lbko,86
228
+ langtrace_python_sdk/instrumentation/neo4j/instrumentation.py,sha256=KECuFv7OuVBgh_NTZl4_W18GAGbKnaeQqRZM8NPZgjU,1668
229
+ langtrace_python_sdk/instrumentation/neo4j/patch.py,sha256=wPAxslFdsHdYU5k1nHzWAqaHxQA-HhxgfVnb_U5qaZ0,7922
221
230
  langtrace_python_sdk/instrumentation/neo4j_graphrag/__init__.py,sha256=K-Qpfh-kn2EPxnYZ_oubLZNqAUO9Cx7mnMrJu_ms3UU,102
222
231
  langtrace_python_sdk/instrumentation/neo4j_graphrag/instrumentation.py,sha256=FLnddPSozuu5puqYD_FnXLMFet8YToVdWP-cY5QZrvM,2216
223
232
  langtrace_python_sdk/instrumentation/neo4j_graphrag/patch.py,sha256=4c7NKcTJeYsbi5V4aSsuPzTiFoBqtlcXmYx2bMlE7qg,9713
@@ -248,11 +257,11 @@ langtrace_python_sdk/instrumentation/vertexai/instrumentation.py,sha256=yz4trw0B
248
257
  langtrace_python_sdk/instrumentation/vertexai/patch.py,sha256=PzBio8x6zdVpX286TKtaTR-sf1HCHQ7RrdvpyNaGk4Q,5571
249
258
  langtrace_python_sdk/instrumentation/weaviate/__init__.py,sha256=Mc-Je6evPo-kKQzerTG7bd1XO5JOh4YGTE3wBxaUBwg,99
250
259
  langtrace_python_sdk/instrumentation/weaviate/instrumentation.py,sha256=Kwq5QQTUQNRHrWrMnNe9X0TcqtXGiNpBidsuToRTqG0,2417
251
- langtrace_python_sdk/instrumentation/weaviate/patch.py,sha256=Lqixz32uAvDA2VLU3zXLiJ9ohpKeD_LveahX7uro3ZY,6934
260
+ langtrace_python_sdk/instrumentation/weaviate/patch.py,sha256=igqYUR_bEjs1XtyyZ8z3N2Eb3pbtjb6gqeEhVtnLKxw,7036
252
261
  langtrace_python_sdk/types/__init__.py,sha256=SJSJzkgPjGGTVJXUZ_FyR3p9DJ5kWGx7iAnJfY4ZYHU,4669
253
262
  langtrace_python_sdk/utils/__init__.py,sha256=VVDOG-QLd59ZvSHp0avjof0sbxlZ1QQOf0KoOF7ofhQ,3310
254
263
  langtrace_python_sdk/utils/langtrace_sampler.py,sha256=BupNndHbU9IL_wGleKetz8FdcveqHMBVz1bfKTTW80w,1753
255
- langtrace_python_sdk/utils/llm.py,sha256=UGfCfOcQ6NiGKsA1_aJt9Pt7yi4iGKq26TJQroOwktg,23463
264
+ langtrace_python_sdk/utils/llm.py,sha256=UOPgt8OcOyjBiBEtxWGYBVLg9EfVCBLyusgcVwLr8Us,23425
256
265
  langtrace_python_sdk/utils/misc.py,sha256=LaQr5LOmZMiuwVdjYh7aIu6o2C_Xb1wgpQGNOVmRzfE,1918
257
266
  langtrace_python_sdk/utils/prompt_registry.py,sha256=n5dQMVLBw8aJZY8Utvf67bncc25ELf6AH9BYw8_hSzo,2619
258
267
  langtrace_python_sdk/utils/sdk_version_checker.py,sha256=F-VVVH7Fmhr5LcY0IIe-34zIi5RQcx26uuxFpPzZesM,1782
@@ -303,8 +312,8 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
303
312
  tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
304
313
  tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
305
314
  tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
306
- langtrace_python_sdk-3.8.8.dist-info/METADATA,sha256=deElB8UvrgQqY6ZaOFhY7bKQnvXEinTTrnNkgz4b04o,15844
307
- langtrace_python_sdk-3.8.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
308
- langtrace_python_sdk-3.8.8.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
309
- langtrace_python_sdk-3.8.8.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
310
- langtrace_python_sdk-3.8.8.dist-info/RECORD,,
315
+ langtrace_python_sdk-3.8.10.dist-info/METADATA,sha256=-4u_t1c_jWQZ_yk1oIedRtGD9L5gCxcUbJBwfwTbfh0,15845
316
+ langtrace_python_sdk-3.8.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
317
+ langtrace_python_sdk-3.8.10.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
318
+ langtrace_python_sdk-3.8.10.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
319
+ langtrace_python_sdk-3.8.10.dist-info/RECORD,,