trodo-python 2.10.0__tar.gz → 2.10.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {trodo_python-2.10.0 → trodo_python-2.10.3}/PKG-INFO +1 -1
- {trodo_python-2.10.0 → trodo_python-2.10.3}/pyproject.toml +1 -1
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/__init__.py +1 -1
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/auto_instrument.py +39 -6
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/wrap_agent.py +8 -2
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo_python.egg-info/PKG-INFO +1 -1
- {trodo_python-2.10.0 → trodo_python-2.10.3}/README.md +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/setup.cfg +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_anon_distinct_id 2.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_anon_distinct_id.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_auto_instrument_fixes.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_cross_process_session.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_end_run.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_error_enrichment.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_llm_usage_cost.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_processor_methods.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_register_otel.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_start_run.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/tests/test_wrap_agent_unchanged.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/api/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/api/async_client.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/api/endpoints.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/api/http_client.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/auto/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/auto/auto_event_manager.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/client.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/managers/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/managers/group_manager.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/managers/people_manager.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/context.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/helpers.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/processor.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/register.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/otel/transport.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/queue/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/queue/batch_flusher.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/queue/event_queue.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/session/__init__.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/session/server_session.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/session/session_manager.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/types.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo/user_context.py +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo_python.egg-info/SOURCES.txt +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo_python.egg-info/dependency_links.txt +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo_python.egg-info/requires.txt +0 -0
- {trodo_python-2.10.0 → trodo_python-2.10.3}/trodo_python.egg-info/top_level.txt +0 -0
|
@@ -9,12 +9,25 @@ lazily and skip anything that isn't installed.
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
+
import sys
|
|
12
13
|
from datetime import datetime, timezone
|
|
13
14
|
from typing import Any, Callable, Dict, Iterable, List, Optional
|
|
14
15
|
|
|
15
16
|
from .context import get_active_context
|
|
16
17
|
from .processor import TrodoSpan, TrodoSpanProcessor
|
|
17
18
|
|
|
19
|
+
# Always-on, one-shot warnings. Silent skips (missing opentelemetry-sdk) are the
|
|
20
|
+
# #1 cause of "I installed Trodo but see no LLM spans" — surface them even
|
|
21
|
+
# without debug, matching the Node SDK's warnOnce behaviour.
|
|
22
|
+
_WARNED_ONCE: set = set()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _warn_once(key: str, msg: str) -> None:
|
|
26
|
+
if key in _WARNED_ONCE:
|
|
27
|
+
return
|
|
28
|
+
_WARNED_ONCE.add(key)
|
|
29
|
+
sys.stderr.write(f"[trodo-python] {msg}\n")
|
|
30
|
+
|
|
18
31
|
|
|
19
32
|
def _hr_to_iso(nanos: Optional[int]) -> Optional[str]:
|
|
20
33
|
if nanos is None:
|
|
@@ -263,11 +276,24 @@ def _register_instrumentors() -> None:
|
|
|
263
276
|
LlamaIndexInstrumentor().instrument()
|
|
264
277
|
|
|
265
278
|
def _google_generativeai() -> Any:
|
|
266
|
-
|
|
267
|
-
|
|
279
|
+
import opentelemetry.instrumentation.google_generativeai as _m # type: ignore
|
|
280
|
+
|
|
281
|
+
# The exported class name varies by version: GoogleGenerativeAiInstrumentor
|
|
282
|
+
# (current — note the lowercase 'i'), GoogleGenerativeAIInstrumentor, or
|
|
283
|
+
# GenAIInstrumentor. Importing the wrong casing silently disabled Gemini
|
|
284
|
+
# auto-instrumentation. (This instrumentation patches the new @google/genai
|
|
285
|
+
# SDK, i.e. the `google-genai` package, not legacy google-generativeai.)
|
|
286
|
+
instr = (
|
|
287
|
+
getattr(_m, "GoogleGenerativeAiInstrumentor", None)
|
|
288
|
+
or getattr(_m, "GoogleGenerativeAIInstrumentor", None)
|
|
289
|
+
or getattr(_m, "GenAIInstrumentor", None)
|
|
268
290
|
)
|
|
269
|
-
|
|
270
|
-
|
|
291
|
+
if instr is None:
|
|
292
|
+
raise ImportError(
|
|
293
|
+
"no GoogleGenerativeAi/GenAI Instrumentor in "
|
|
294
|
+
"opentelemetry.instrumentation.google_generativeai"
|
|
295
|
+
)
|
|
296
|
+
instr().instrument()
|
|
271
297
|
|
|
272
298
|
def _vertexai() -> Any:
|
|
273
299
|
from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor # type: ignore
|
|
@@ -328,14 +354,21 @@ def enable_auto_instrument(
|
|
|
328
354
|
"""Register OTel auto-instrumentations for installed packages.
|
|
329
355
|
|
|
330
356
|
Returns the list of framework ids that were actually instrumented.
|
|
331
|
-
|
|
332
|
-
instrumentation
|
|
357
|
+
Emits a one-shot stderr warning if opentelemetry-sdk isn't installed (the
|
|
358
|
+
#1 silent-failure mode); per-framework instrumentation packages that aren't
|
|
359
|
+
installed are skipped silently.
|
|
333
360
|
"""
|
|
334
361
|
disabled = set(disable or [])
|
|
335
362
|
try:
|
|
336
363
|
from opentelemetry import trace # type: ignore
|
|
337
364
|
from opentelemetry.sdk.trace import TracerProvider # type: ignore
|
|
338
365
|
except Exception:
|
|
366
|
+
_warn_once(
|
|
367
|
+
"otel-sdk-missing",
|
|
368
|
+
"auto-instrument: opentelemetry-sdk is not installed — no LLM spans "
|
|
369
|
+
"will be auto-captured. Install: pip install opentelemetry-sdk "
|
|
370
|
+
"opentelemetry-api (plus opentelemetry-instrumentation-<provider> per framework).",
|
|
371
|
+
)
|
|
339
372
|
return []
|
|
340
373
|
|
|
341
374
|
provider = trace.get_tracer_provider()
|
|
@@ -253,8 +253,14 @@ class RunHandle:
|
|
|
253
253
|
def set_output(self, value: Any) -> None:
|
|
254
254
|
self.output = _prepare_value(value)
|
|
255
255
|
|
|
256
|
-
def set_metadata(self, **kwargs: Any) -> None:
|
|
257
|
-
|
|
256
|
+
def set_metadata(self, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any) -> None:
|
|
257
|
+
# Accept a dict (Node parity: setMetadata({...})) and/or keyword args
|
|
258
|
+
# (set_metadata(key=value)). Previously kwargs-only, which broke code
|
|
259
|
+
# copied from the Node SDK.
|
|
260
|
+
if metadata:
|
|
261
|
+
self.metadata.update(metadata)
|
|
262
|
+
if kwargs:
|
|
263
|
+
self.metadata.update(kwargs)
|
|
258
264
|
|
|
259
265
|
def set_error_summary(self, summary: str, *, type: Optional[str] = None) -> None:
|
|
260
266
|
"""Mark the run as errored without raising — e.g. a soft failure the
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|