docent-python 0.1.3a0__py3-none-any.whl → 0.1.5a0__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.

Potentially problematic release.


This version of docent-python might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docent-python
3
- Version: 0.1.3a0
3
+ Version: 0.1.5a0
4
4
  Summary: Docent SDK
5
5
  Project-URL: Homepage, https://github.com/TransluceAI/docent
6
6
  Project-URL: Issues, https://github.com/TransluceAI/docent/issues
@@ -22,4 +22,3 @@ Requires-Dist: pydantic>=2.11.7
22
22
  Requires-Dist: pyyaml>=6.0.2
23
23
  Requires-Dist: tiktoken>=0.7.0
24
24
  Requires-Dist: tqdm>=4.67.1
25
- Requires-Dist: traceloop-sdk>=0.44.1
@@ -1,29 +1,29 @@
1
1
  docent/__init__.py,sha256=J2BbO6rzilfw9WXRUeolr439EGFezqbMU_kCpCCryRA,59
2
2
  docent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- docent/trace.py,sha256=Z0lAPwVzXjFvxpiU-CuvfWIslq9Q4alNkZMoQ77Xudk,40711
4
- docent/trace_alt.py,sha256=JmHJyDXdEAJ-qVg_e4qYlQrslj9q103wKZvq_c40G0o,17213
3
+ docent/trace.py,sha256=aPbV9fy_JpFq9y3yuqhlHKPm2QiNh9SLsKOL2azxghs,62611
4
+ docent/trace_temp.py,sha256=Z0lAPwVzXjFvxpiU-CuvfWIslq9Q4alNkZMoQ77Xudk,40711
5
5
  docent/_log_util/__init__.py,sha256=3HXXrxrSm8PxwG4llotrCnSnp7GuroK1FNHsdg6f7aE,73
6
6
  docent/_log_util/logger.py,sha256=kwM0yRW1IJd6-XTorjWn48B4l8qvD2ZM6VDjY5eskQI,4422
7
- docent/data_models/__init__.py,sha256=-F8Er1RXPX6SEKFLnoi6OMhHq57KJqyHx1McP2rCsGQ,483
7
+ docent/data_models/__init__.py,sha256=4JbTDVzRhS5VZgo8MALwd_YI17GaN7X9E3rOc4Xl7kw,327
8
8
  docent/data_models/_tiktoken_util.py,sha256=hC0EDDWItv5-0cONBnHWgZtQOflDU7ZNEhXPFo4DvPc,3057
9
- docent/data_models/agent_run.py,sha256=sdvoUUpOhQAHqJHNR5KoHthCXrpJajdIREMacoR1ODk,9516
9
+ docent/data_models/agent_run.py,sha256=lw-odD2zzFi-RGvkAFjz9x8l6XWPrGT6uRGqTj9h8qU,9621
10
10
  docent/data_models/citation.py,sha256=WsVQZcBT2EJD24ysyeVOC5Xfo165RI7P5_cOnJBgHj0,10015
11
- docent/data_models/metadata.py,sha256=oq2rO0a-914YKKznz-yrlQR28gBAmryRrwZL0QiaBGg,8702
11
+ docent/data_models/metadata.py,sha256=r0SYC4i2x096dXMLfw_rAMtcJQCsoV6EOMPZuEngbGA,9062
12
12
  docent/data_models/regex.py,sha256=0ciIerkrNwb91bY5mTcyO5nDWH67xx2tZYObV52fmBo,1684
13
13
  docent/data_models/shared_types.py,sha256=jjm-Dh5S6v7UKInW7SEqoziOsx6Z7Uu4e3VzgCbTWvc,225
14
- docent/data_models/transcript.py,sha256=K6q40-EoSe-escmunX22LrN2T9QhPhxI9S9hgUaKx-4,13851
14
+ docent/data_models/transcript.py,sha256=NDcpvil4dJ8YhG_JJ0X-w0prkXhwhsdO-zoL-CZMipM,15446
15
15
  docent/data_models/chat/__init__.py,sha256=O04XQ2NmO8GTWqkkB_Iydj8j_CucZuLhoyMVTxJN_cs,570
16
16
  docent/data_models/chat/content.py,sha256=Co-jO8frQa_DSP11wJuhPX0s-GpJk8yqtKqPeiAIZ_U,1672
17
17
  docent/data_models/chat/message.py,sha256=iAo38kbV6wYbFh8S23cxLy6HY4C_i3PzQ6RpSQG5dxM,3861
18
18
  docent/data_models/chat/tool.py,sha256=x7NKINswPe0Kqvcx4ubjHzB-n0-i4DbFodvaBb2vitk,3042
19
- docent/loaders/load_inspect.py,sha256=NEubsHMVseCV0r-XBEcLPB6aGj6215dFAvGQSF1jlSI,2365
19
+ docent/loaders/load_inspect.py,sha256=yK6LZgprT8kc0Jg4N_cnbhsGCq9lINmMcgALXA9AibY,2812
20
20
  docent/samples/__init__.py,sha256=roDFnU6515l9Q8v17Es_SpWyY9jbm5d6X9lV01V0MZo,143
21
21
  docent/samples/load.py,sha256=ZGE07r83GBNO4A0QBh5aQ18WAu3mTWA1vxUoHd90nrM,207
22
22
  docent/samples/log.eval,sha256=orrW__9WBfANq7NwKsPSq9oTsQRcG6KohG5tMr_X_XY,397708
23
23
  docent/samples/tb_airline.json,sha256=eR2jFFRtOw06xqbEglh6-dPewjifOk-cuxJq67Dtu5I,47028
24
24
  docent/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- docent/sdk/client.py,sha256=uyhTisb9bHk7Hd2G4UKLdfvuiAmYOOqJiwEPbYWN9IE,12371
26
- docent_python-0.1.3a0.dist-info/METADATA,sha256=1MaUbt-Jf03yM3185m2sslYO5oH9BjcdjwxbQnWKfF8,1074
27
- docent_python-0.1.3a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
- docent_python-0.1.3a0.dist-info/licenses/LICENSE.md,sha256=vOHzq3K4Ndu0UV9hPrtXvlD7pHOjyDQmGjHuLSIkRQY,1087
29
- docent_python-0.1.3a0.dist-info/RECORD,,
25
+ docent/sdk/client.py,sha256=fLdniy8JzMLoZpaS9SP2pHban_ToavgtI8VeHZLMNZo,12773
26
+ docent_python-0.1.5a0.dist-info/METADATA,sha256=XRzyvevWQ36Mk6UB6HIGIuD6vCQBX0cazhZylY25Q24,1037
27
+ docent_python-0.1.5a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
+ docent_python-0.1.5a0.dist-info/licenses/LICENSE.md,sha256=vOHzq3K4Ndu0UV9hPrtXvlD7pHOjyDQmGjHuLSIkRQY,1087
29
+ docent_python-0.1.5a0.dist-info/RECORD,,
docent/trace_alt.py DELETED
@@ -1,497 +0,0 @@
1
- import asyncio
2
- import atexit
3
- import functools
4
- import logging
5
- import os
6
- import uuid
7
- from contextlib import asynccontextmanager, contextmanager
8
- from contextvars import ContextVar, Token
9
- from typing import Any, AsyncIterator, Callable, Dict, Iterator, Optional, Set
10
-
11
- import requests
12
- from opentelemetry.context import Context
13
- from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor
14
- from opentelemetry.trace import Span
15
- from traceloop.sdk import Traceloop
16
-
17
- DEFAULT_ENDPOINT = "https://api.docent.transluce.org/rest/telemetry"
18
-
19
- # Context variables for tracking current agent run and collection
20
- _current_agent_run_id: ContextVar[Optional[str]] = ContextVar("current_agent_run_id", default=None)
21
- _current_collection_id: ContextVar[Optional[str]] = ContextVar(
22
- "current_collection_id", default=None
23
- )
24
-
25
- # Global configuration
26
- _tracing_initialized = False
27
- _collection_name: Optional[str] = None
28
- _collection_id: Optional[str] = None
29
- _endpoint: Optional[str] = None
30
- _api_key: Optional[str] = None
31
- _enable_console_export = False
32
- _disable_batch = False
33
- _instruments: Optional[Set[Any]] = None
34
- _block_instruments: Optional[Set[Any]] = None
35
-
36
-
37
- class DocentSpanProcessor(SpanProcessor):
38
- """Custom span processor to add Docent metadata to spans.
39
-
40
- This processor integrates cleanly with Traceloop's existing span processing
41
- and adds Docent-specific attributes to all spans.
42
- """
43
-
44
- def __init__(self, collection_id: str, enable_console_export: bool = False):
45
- self.collection_id = collection_id
46
- self.enable_console_export = enable_console_export
47
-
48
- def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None:
49
- """Add Docent metadata when a span starts."""
50
- # Always add collection_id
51
- span.set_attribute("collection_id", self.collection_id)
52
-
53
- # Add agent_run_id if available
54
- agent_run_id = _get_current_agent_run_id()
55
- if agent_run_id:
56
- span.set_attribute("agent_run_id", agent_run_id)
57
- else:
58
- # If no agent_run_id in context, mark this as a default span
59
- span.set_attribute("agent_run_id_default", True)
60
-
61
- # Add service name for better integration with existing OTEL setups
62
- span.set_attribute("service.name", _collection_name or "docent-service")
63
-
64
- if self.enable_console_export:
65
- logging.debug(
66
- f"Span started - collection_id: {self.collection_id}, agent_run_id: {agent_run_id}"
67
- )
68
-
69
- def on_end(self, span: ReadableSpan) -> None:
70
- pass
71
-
72
- def shutdown(self) -> None:
73
- """Called when the processor is shut down."""
74
-
75
- def force_flush(self, timeout_millis: float = 30000) -> bool:
76
- """Force flush any pending spans."""
77
- return True
78
-
79
-
80
- def initialize_tracing(
81
- collection_name: str,
82
- collection_id: Optional[str] = None,
83
- endpoint: Optional[str] = None,
84
- api_key: Optional[str] = None,
85
- enable_console_export: bool = False,
86
- disable_batch: bool = False,
87
- instruments: Optional[Set[Any]] = None,
88
- block_instruments: Optional[Set[Any]] = None,
89
- ) -> None:
90
- """Initialize Docent tracing with the specified configuration.
91
-
92
- This function provides a comprehensive initialization that integrates cleanly
93
- with existing OpenTelemetry setups and provides extensive configuration options.
94
-
95
- Args:
96
- collection_name: Name for your application/collection
97
- collection_id: Optional collection ID (auto-generated if not provided)
98
- endpoint: Optional OTLP endpoint URL (defaults to Docent's hosted service)
99
- api_key: Optional API key (uses DOCENT_API_KEY environment variable if not provided)
100
- enable_console_export: Whether to also export traces to console for debugging
101
- disable_batch: Whether to disable batch processing (use SimpleSpanProcessor)
102
- instruments: Set of instruments to enable (None = all instruments)
103
- block_instruments: Set of instruments to explicitly disable
104
- """
105
- global _tracing_initialized, _collection_name, _collection_id, _endpoint, _api_key
106
- global _enable_console_export, _disable_batch, _instruments, _block_instruments
107
-
108
- if _tracing_initialized:
109
- logging.warning("Docent tracing already initialized")
110
- return
111
-
112
- _collection_name = collection_name
113
- _collection_id = collection_id or _generate_id()
114
- _endpoint = endpoint or DEFAULT_ENDPOINT
115
- _api_key = api_key or os.getenv("DOCENT_API_KEY")
116
- _enable_console_export = enable_console_export
117
- _disable_batch = disable_batch
118
- _instruments = instruments
119
- _block_instruments = block_instruments
120
-
121
- _set_current_collection_id(_collection_id)
122
-
123
- if not _api_key:
124
- raise ValueError(
125
- "API key is required. Set DOCENT_API_KEY environment variable or pass api_key parameter."
126
- )
127
-
128
- # Initialize Traceloop with comprehensive configuration
129
-
130
- # Get Traceloop's default span processor
131
- from traceloop.sdk.tracing.tracing import get_default_span_processor
132
-
133
- # Create our custom context span processor (only adds metadata, doesn't export)
134
- docent_processor = DocentSpanProcessor(_collection_id, enable_console_export)
135
-
136
- # Get Traceloop's default span processor for export
137
- traceloop_processor = get_default_span_processor(
138
- disable_batch=_disable_batch,
139
- api_endpoint=_endpoint,
140
- headers={"Authorization": f"Bearer {_api_key}"},
141
- )
142
-
143
- # Combine both processors
144
- processors = [docent_processor, traceloop_processor]
145
-
146
- os.environ["TRACELOOP_METRICS_ENABLED"] = "false"
147
- os.environ["TRACELOOP_TRACE_ENABLED"] = "true"
148
- # Temporarily redirect stdout to suppress Traceloop's print statements
149
- # with redirect_stdout(io.StringIO()):
150
- Traceloop.init( # type: ignore
151
- app_name=collection_name,
152
- api_endpoint=_endpoint,
153
- api_key=_api_key,
154
- telemetry_enabled=False, # don't send telemetry to traceloop's backend
155
- disable_batch=_disable_batch,
156
- instruments=_instruments,
157
- block_instruments=_block_instruments,
158
- processor=processors, # Add both our context processor and Traceloop's export processor
159
- )
160
-
161
- _tracing_initialized = True
162
- logging.info(
163
- f"Docent tracing initialized for collection: {collection_name} with collection_id: {_collection_id}"
164
- )
165
-
166
- # Register cleanup handlers
167
- atexit.register(_cleanup_tracing)
168
-
169
-
170
- def _cleanup_tracing() -> None:
171
- """Clean up tracing resources on shutdown."""
172
- global _tracing_initialized
173
- if _tracing_initialized:
174
- try:
175
- # Notify API that the trace is over
176
- _notify_trace_done()
177
-
178
- logging.info("Docent tracing cleanup completed")
179
- except Exception as e:
180
- logging.warning(f"Error during tracing cleanup: {e}")
181
- finally:
182
- _tracing_initialized = False
183
-
184
-
185
- def _ensure_tracing_initialized():
186
- """Ensure tracing has been initialized before use."""
187
- if not _tracing_initialized:
188
- raise RuntimeError("Docent tracing not initialized. Call initialize_tracing() first.")
189
-
190
-
191
- def _generate_id() -> str:
192
- """Generate a unique ID for agent runs or collections."""
193
- return str(uuid.uuid4())
194
-
195
-
196
- def _get_current_agent_run_id() -> Optional[str]:
197
- """Get the current agent run ID from context."""
198
- return _current_agent_run_id.get()
199
-
200
-
201
- def _get_current_collection_id() -> Optional[str]:
202
- """Get the current collection ID from context."""
203
- return _current_collection_id.get()
204
-
205
-
206
- def _set_current_agent_run_id(agent_run_id: Optional[str]) -> Token[Optional[str]]:
207
- """Set the current agent run ID in context."""
208
- return _current_agent_run_id.set(agent_run_id)
209
-
210
-
211
- def _set_current_collection_id(collection_id: Optional[str]) -> Token[Optional[str]]:
212
- """Set the current collection ID in context."""
213
- return _current_collection_id.set(collection_id)
214
-
215
-
216
- def _send_to_api(endpoint: str, data: Dict[str, Any]) -> None:
217
- """Send data to the Docent API endpoint.
218
-
219
- Args:
220
- endpoint: The API endpoint URL
221
- data: The data to send
222
- """
223
- try:
224
- headers = {"Content-Type": "application/json", "Authorization": f"Bearer {_api_key}"}
225
-
226
- response = requests.post(endpoint, json=data, headers=headers, timeout=10)
227
- response.raise_for_status()
228
-
229
- logging.debug(f"Successfully sent data to {endpoint}")
230
- except requests.exceptions.RequestException as e:
231
- logging.error(f"Failed to send data to {endpoint}: {e}")
232
- except Exception as e:
233
- logging.error(f"Unexpected error sending data to {endpoint}: {e}")
234
-
235
-
236
- def _notify_trace_done() -> None:
237
- """Notify the Docent API that the trace is done."""
238
- collection_id = _get_current_collection_id()
239
- if collection_id and _endpoint:
240
- data = {"collection_id": collection_id, "status": "completed"}
241
- _send_to_api(f"{_endpoint}/v1/trace-done", data)
242
-
243
-
244
- def agent_run_score(name: str, score: float, attributes: Optional[Dict[str, Any]] = None) -> None:
245
- """
246
- Record a score event on the current span.
247
- Automatically works in both sync and async contexts.
248
-
249
- Args:
250
- name: Name of the score metric
251
- score: Numeric score value
252
- attributes: Optional additional attributes for the score event
253
- """
254
- _ensure_tracing_initialized()
255
-
256
- agent_run_id = _get_current_agent_run_id()
257
- if not agent_run_id:
258
- logging.warning("No active agent run context. Score will not be sent.")
259
- return
260
-
261
- collection_id = _get_current_collection_id() or _collection_id
262
- if not collection_id:
263
- logging.warning("No collection ID available. Score will not be sent.")
264
- return
265
-
266
- # Send score directly to API
267
- score_data = {
268
- "collection_id": collection_id,
269
- "agent_run_id": agent_run_id,
270
- "score_name": name,
271
- "score_value": score,
272
- }
273
-
274
- # Add additional attributes if provided
275
- if attributes:
276
- score_data.update(attributes)
277
-
278
- _send_to_api(f"{_endpoint}/v1/scores", score_data)
279
-
280
-
281
- def agent_run_metadata(metadata: Dict[str, Any]) -> None:
282
- """Attach metadata to the current agent run.
283
-
284
- Args:
285
- metadata: Dictionary of metadata to attach
286
- """
287
- _ensure_tracing_initialized()
288
-
289
- agent_run_id = _get_current_agent_run_id()
290
- if not agent_run_id:
291
- logging.warning("No active agent run context. Metadata will not be sent.")
292
- return
293
-
294
- collection_id = _get_current_collection_id() or _collection_id
295
- if not collection_id:
296
- logging.warning("No collection ID available. Metadata will not be sent.")
297
- return
298
-
299
- # Send metadata directly to API
300
- metadata_data = {
301
- "collection_id": collection_id,
302
- "agent_run_id": agent_run_id,
303
- "metadata": metadata,
304
- }
305
-
306
- _send_to_api(f"{_endpoint}/v1/metadata", metadata_data)
307
-
308
-
309
- @contextmanager
310
- def _agent_run_context_sync(
311
- agent_run_id: Optional[str] = None,
312
- metadata: Optional[Dict[str, Any]] = None,
313
- ) -> Iterator[tuple[str, Optional[str]]]:
314
- """Synchronous context manager for creating and managing agent runs."""
315
- _ensure_tracing_initialized()
316
-
317
- # Generate IDs if not provided
318
- current_agent_run_id = agent_run_id or _generate_id()
319
-
320
- # Set up context
321
- agent_run_token = _set_current_agent_run_id(current_agent_run_id)
322
-
323
- try:
324
- # Send metadata to API if provided
325
- if metadata:
326
- agent_run_metadata(metadata)
327
-
328
- # Yield the agent run ID and None for transcript_id (handled by backend)
329
- # Traceloop will automatically create spans for any instrumented operations
330
- # and our DocentSpanProcessor will add the appropriate metadata
331
- yield (current_agent_run_id, None)
332
- finally:
333
- # Restore context
334
- _current_agent_run_id.reset(agent_run_token)
335
-
336
-
337
- @asynccontextmanager
338
- async def _agent_run_context_async(
339
- agent_run_id: Optional[str] = None,
340
- metadata: Optional[Dict[str, Any]] = None,
341
- ) -> AsyncIterator[tuple[str, Optional[str]]]:
342
- """Asynchronous context manager for creating and managing agent runs."""
343
- _ensure_tracing_initialized()
344
-
345
- # Generate IDs if not provided
346
- current_agent_run_id = agent_run_id or _generate_id()
347
-
348
- # Set up context
349
- agent_run_token = _set_current_agent_run_id(current_agent_run_id)
350
-
351
- try:
352
- # Send metadata to API if provided
353
- if metadata:
354
- agent_run_metadata(metadata)
355
-
356
- # Yield the agent run ID and None for transcript_id (handled by backend)
357
- # Traceloop will automatically create spans for any instrumented operations
358
- # and our DocentSpanProcessor will add the appropriate metadata
359
- yield (current_agent_run_id, None)
360
- finally:
361
- # Restore context
362
- _current_agent_run_id.reset(agent_run_token)
363
-
364
-
365
- def agent_run_context(
366
- agent_run_id: Optional[str] = None,
367
- metadata: Optional[Dict[str, Any]] = None,
368
- ):
369
- """Context manager for creating and managing agent runs.
370
-
371
- This context manager can be used in both synchronous and asynchronous contexts.
372
- In async contexts, use it with `async with agent_run_context()`.
373
- In sync contexts, use it with `with agent_run_context()`.
374
-
375
- Args:
376
- agent_run_id: Optional agent run ID (auto-generated if not provided)
377
- metadata: Optional metadata to attach to the agent run
378
-
379
- Returns:
380
- A context manager that yields a tuple of (agent_run_id, transcript_id)
381
- where transcript_id is None for now as it's handled by backend
382
- """
383
- # Check if we're in an async context by looking at the current frame
384
- import inspect
385
-
386
- frame = inspect.currentframe()
387
- try:
388
- # Look for async context indicators in the call stack
389
- while frame:
390
- if frame.f_code.co_flags & 0x80: # CO_COROUTINE flag
391
- return _agent_run_context_async(agent_run_id=agent_run_id, metadata=metadata)
392
- frame = frame.f_back
393
- finally:
394
- # Clean up the frame reference
395
- del frame
396
-
397
- # Default to sync context manager
398
- return _agent_run_context_sync(agent_run_id=agent_run_id, metadata=metadata)
399
-
400
-
401
- def agent_run(
402
- func: Optional[Callable[..., Any]] = None,
403
- *,
404
- agent_run_id: Optional[str] = None,
405
- metadata: Optional[Dict[str, Any]] = None,
406
- ) -> Callable[..., Any]:
407
- """Decorator for creating agent runs around functions.
408
-
409
- Args:
410
- func: Function to decorate
411
- agent_run_id: Optional agent run ID (auto-generated if not provided)
412
- metadata: Optional metadata to attach to the agent run
413
-
414
- Returns:
415
- Decorated function
416
- """
417
-
418
- def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
419
- @functools.wraps(func)
420
- def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
421
- with _agent_run_context_sync(agent_run_id=agent_run_id, metadata=metadata) as (
422
- run_id,
423
- _,
424
- ):
425
- result = func(*args, **kwargs)
426
- # Store agent run ID as an attribute for access
427
- setattr(sync_wrapper, "docent", type("DocentInfo", (), {"agent_run_id": run_id})()) # type: ignore
428
- return result
429
-
430
- @functools.wraps(func)
431
- async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
432
- async with _agent_run_context_async(agent_run_id=agent_run_id, metadata=metadata) as (
433
- run_id,
434
- _,
435
- ):
436
- result = await func(*args, **kwargs)
437
- # Store agent run ID as an attribute for access
438
- setattr(async_wrapper, "docent", type("DocentInfo", (), {"agent_run_id": run_id})()) # type: ignore
439
- return result
440
-
441
- # Return appropriate wrapper based on function type
442
- if asyncio.iscoroutinefunction(func):
443
- return async_wrapper
444
- else:
445
- return sync_wrapper
446
-
447
- # Handle both @agent_run and @agent_run(agent_run_id=..., metadata=...)
448
- if func is None:
449
- return decorator
450
- else:
451
- return decorator(func)
452
-
453
-
454
- # Additional utility functions for better integration
455
-
456
-
457
- def get_current_agent_run_id() -> Optional[str]:
458
- """Get the current agent run ID from context.
459
-
460
- Returns:
461
- The current agent run ID if available, None otherwise
462
- """
463
- return _get_current_agent_run_id()
464
-
465
-
466
- def get_current_collection_id() -> Optional[str]:
467
- """Get the current collection ID from context.
468
-
469
- Returns:
470
- The current collection ID if available, None otherwise
471
- """
472
- return _get_current_collection_id()
473
-
474
-
475
- def is_tracing_initialized() -> bool:
476
- """Check if tracing has been initialized.
477
-
478
- Returns:
479
- True if tracing is initialized, False otherwise
480
- """
481
- return _tracing_initialized
482
-
483
-
484
- def flush_spans() -> None:
485
- """Force flush any pending spans to the backend.
486
-
487
- This is useful for ensuring all spans are sent before shutdown
488
- or for debugging purposes.
489
- """
490
- if _tracing_initialized:
491
- try:
492
- traceloop_instance = Traceloop.get()
493
- if hasattr(traceloop_instance, "flush"):
494
- traceloop_instance.flush() # type: ignore
495
- logging.debug("Spans flushed successfully")
496
- except Exception as e:
497
- logging.warning(f"Error flushing spans: {e}")