tracecast 0.2.7__tar.gz → 0.2.8__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.
Files changed (107) hide show
  1. {tracecast-0.2.7/tracecast.egg-info → tracecast-0.2.8}/PKG-INFO +1 -1
  2. {tracecast-0.2.7 → tracecast-0.2.8}/pyproject.toml +1 -1
  3. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/__init__.py +2 -2
  4. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrument.py +18 -0
  5. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/openai_inst.py +36 -24
  6. {tracecast-0.2.7 → tracecast-0.2.8/tracecast.egg-info}/PKG-INFO +1 -1
  7. {tracecast-0.2.7 → tracecast-0.2.8}/LICENSE +0 -0
  8. {tracecast-0.2.7 → tracecast-0.2.8}/README.md +0 -0
  9. {tracecast-0.2.7 → tracecast-0.2.8}/setup.cfg +0 -0
  10. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_aggregator_graph.py +0 -0
  11. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_context_propagation.py +0 -0
  12. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_cost_calculator.py +0 -0
  13. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_dashboard_mount.py +0 -0
  14. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_dashboard_pushdown.py +0 -0
  15. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_dashboard_sessions.py +0 -0
  16. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_decorators.py +0 -0
  17. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_e2e_langgraph.py +0 -0
  18. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_exporters_db.py +0 -0
  19. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_integration_frameworks.py +0 -0
  20. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_integration_langchain.py +0 -0
  21. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_json_exporter.py +0 -0
  22. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_langchain_callback.py +0 -0
  23. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_llm_wrappers.py +0 -0
  24. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_logging.py +0 -0
  25. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_mongo_exporter.py +0 -0
  26. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_prompt_dashboard.py +0 -0
  27. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_prompts.py +0 -0
  28. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_roundtrip.py +0 -0
  29. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_schema_v2.py +0 -0
  30. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_score.py +0 -0
  31. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_score_dashboard.py +0 -0
  32. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_scoring_api.py +0 -0
  33. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_serve.py +0 -0
  34. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_span.py +0 -0
  35. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_streaming.py +0 -0
  36. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_token_counter.py +0 -0
  37. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_trace.py +0 -0
  38. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_trace_span.py +0 -0
  39. {tracecast-0.2.7 → tracecast-0.2.8}/tests/test_tracer.py +0 -0
  40. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/__init__.py +0 -0
  41. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/cost_calculator.py +0 -0
  42. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/logger.py +0 -0
  43. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/scoring.py +0 -0
  44. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/token_counter.py +0 -0
  45. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/core/tracer.py +0 -0
  46. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/__init__.py +0 -0
  47. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/aggregator.py +0 -0
  48. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/asgi_middleware.py +0 -0
  49. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/blueprint.py +0 -0
  50. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/eval_reader.py +0 -0
  51. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/prompt_reader.py +0 -0
  52. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/reader.py +0 -0
  53. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/router.py +0 -0
  54. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/score_reader.py +0 -0
  55. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/standalone.py +0 -0
  56. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/assets/index-B07hiBI2.js +0 -0
  57. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/assets/index-BMIlEmLS.js +0 -0
  58. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/assets/index-CY5YOA8F.js +0 -0
  59. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/assets/index-DllJJzmE.css +0 -0
  60. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/assets/index-Dt0awpJJ.js +0 -0
  61. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/dashboard/static/index.html +0 -0
  62. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/decorators.py +0 -0
  63. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/__init__.py +0 -0
  64. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/cli.py +0 -0
  65. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/compare.py +0 -0
  66. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/dataset.py +0 -0
  67. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/decorator.py +0 -0
  68. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/judge.py +0 -0
  69. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/metrics.py +0 -0
  70. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/models.py +0 -0
  71. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/online.py +0 -0
  72. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/runner.py +0 -0
  73. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/eval/scorers.py +0 -0
  74. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/__init__.py +0 -0
  75. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/_eval_store.py +0 -0
  76. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/base.py +0 -0
  77. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/dict_exporter.py +0 -0
  78. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/json_file.py +0 -0
  79. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/mongo.py +0 -0
  80. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/postgres.py +0 -0
  81. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/exporters/query.py +0 -0
  82. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/__init__.py +0 -0
  83. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/_llamaindex_handler.py +0 -0
  84. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/_streaming.py +0 -0
  85. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/anthropic_inst.py +0 -0
  86. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/base.py +0 -0
  87. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/crewai_inst.py +0 -0
  88. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/gemini_inst.py +0 -0
  89. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/langchain_inst.py +0 -0
  90. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/instrumentors/llamaindex_inst.py +0 -0
  91. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/integrations/__init__.py +0 -0
  92. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/integrations/langchain.py +0 -0
  93. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/integrations/llm.py +0 -0
  94. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/middleware.py +0 -0
  95. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/models/__init__.py +0 -0
  96. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/models/score.py +0 -0
  97. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/models/span.py +0 -0
  98. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/models/trace.py +0 -0
  99. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/prompts/__init__.py +0 -0
  100. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/prompts/client.py +0 -0
  101. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/prompts/models.py +0 -0
  102. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast/serve.py +0 -0
  103. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast.egg-info/SOURCES.txt +0 -0
  104. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast.egg-info/dependency_links.txt +0 -0
  105. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast.egg-info/entry_points.txt +0 -0
  106. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast.egg-info/requires.txt +0 -0
  107. {tracecast-0.2.7 → tracecast-0.2.8}/tracecast.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracecast
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: LLM observability SDK — framework-agnostic tracing for AI applications
5
5
  Author: Pedro Castanheira Costa
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tracecast"
7
- version = "0.2.7"
7
+ version = "0.2.8"
8
8
  description = "LLM observability SDK — framework-agnostic tracing for AI applications"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -8,7 +8,7 @@ from .decorators import trace_cast, trace_span, set_default_tracer
8
8
  from .core.scoring import score
9
9
  from .prompts import create_prompt, get_prompt, set_label, PromptVersion
10
10
  from .integrations.llm import trace_llm_call, wrap_openai, wrap_anthropic
11
- from .instrument import auto_instrument
11
+ from .instrument import auto_instrument, instrument_openai
12
12
  from .exporters.dict_exporter import DictExporter
13
13
 
14
14
  __all__ = [
@@ -18,5 +18,5 @@ __all__ = [
18
18
  "trace_cast", "trace_span", "set_default_tracer", "score",
19
19
  "create_prompt", "get_prompt", "set_label", "PromptVersion",
20
20
  "trace_llm_call", "wrap_openai", "wrap_anthropic",
21
- "auto_instrument", "DictExporter",
21
+ "auto_instrument", "instrument_openai", "DictExporter",
22
22
  ]
@@ -34,6 +34,24 @@ def auto_instrument(tracer: Optional[Tracer] = None) -> None:
34
34
  _instrumented = True
35
35
 
36
36
 
37
+ def instrument_openai(*, chat: bool = True, embeddings: bool = True, audio: bool = True) -> None:
38
+ """Patch only the requested OpenAI API surfaces, independent of auto_instrument().
39
+
40
+ Use `chat=False` when chat completions are already traced through another
41
+ mechanism (e.g. a manually-wired LangChain callback) and you only want to
42
+ add embeddings/audio coverage — re-patching chat.completions in that case
43
+ would produce duplicate spans for every chat call.
44
+ """
45
+ from .instrumentors.openai_inst import OpenAIInstrumentor
46
+ with _lock:
47
+ inst = _registry.get("openai")
48
+ if inst is None:
49
+ inst = OpenAIInstrumentor()
50
+ _registry["openai"] = inst
51
+ if not inst.is_patched():
52
+ inst.patch(chat=chat, embeddings=embeddings, audio=audio)
53
+
54
+
37
55
  def _reset() -> None:
38
56
  global _instrumented
39
57
  with _lock:
@@ -32,33 +32,44 @@ class OpenAIInstrumentor(BaseInstrumentor):
32
32
  self._original_speech_create: Optional[Any] = None
33
33
  self._patched: bool = False
34
34
 
35
- def patch(self) -> None:
35
+ def patch(self, *, chat: bool = True, embeddings: bool = True, audio: bool = True) -> None:
36
+ """Patch the requested OpenAI API surfaces.
37
+
38
+ `chat=False` lets callers add embeddings/audio coverage without
39
+ re-patching chat.completions — needed when chat completions are
40
+ already traced through another mechanism (e.g. a manually-wired
41
+ LangChain callback), where re-patching would double-count spans.
42
+ """
36
43
  if self._patched:
37
44
  return
38
- import openai.resources.chat.completions as mod
39
45
 
40
- # Sync
41
- self._original_create = mod.Completions.create
42
- self_ref = self
43
- _orig_create = self._original_create
46
+ if chat:
47
+ import openai.resources.chat.completions as mod
48
+
49
+ # Sync
50
+ self._original_create = mod.Completions.create
51
+ self_ref = self
52
+ _orig_create = self._original_create
44
53
 
45
- def patched_create(client_self, *args, **kwargs):
46
- return self_ref._intercept(client_self, args, kwargs, _orig_create)
54
+ def patched_create(client_self, *args, **kwargs):
55
+ return self_ref._intercept(client_self, args, kwargs, _orig_create)
47
56
 
48
- mod.Completions.create = patched_create
57
+ mod.Completions.create = patched_create
49
58
 
50
- # Async
51
- if hasattr(mod, "AsyncCompletions"):
52
- self._original_acreate = mod.AsyncCompletions.create
53
- _orig_acreate = self._original_acreate
59
+ # Async
60
+ if hasattr(mod, "AsyncCompletions"):
61
+ self._original_acreate = mod.AsyncCompletions.create
62
+ _orig_acreate = self._original_acreate
54
63
 
55
- async def patched_acreate(client_self, *args, **kwargs):
56
- return await self_ref._async_intercept(client_self, args, kwargs, _orig_acreate)
64
+ async def patched_acreate(client_self, *args, **kwargs):
65
+ return await self_ref._async_intercept(client_self, args, kwargs, _orig_acreate)
57
66
 
58
- mod.AsyncCompletions.create = patched_acreate
67
+ mod.AsyncCompletions.create = patched_acreate
59
68
 
60
- self._patch_embeddings()
61
- self._patch_audio()
69
+ if embeddings:
70
+ self._patch_embeddings()
71
+ if audio:
72
+ self._patch_audio()
62
73
 
63
74
  self._patched = True
64
75
 
@@ -108,12 +119,13 @@ class OpenAIInstrumentor(BaseInstrumentor):
108
119
  def unpatch(self) -> None:
109
120
  if not self._patched:
110
121
  return
111
- import openai.resources.chat.completions as mod
112
- mod.Completions.create = self._original_create
113
- if self._original_acreate is not None:
114
- mod.AsyncCompletions.create = self._original_acreate
115
- self._original_create = None
116
- self._original_acreate = None
122
+ if self._original_create is not None:
123
+ import openai.resources.chat.completions as mod
124
+ mod.Completions.create = self._original_create
125
+ if self._original_acreate is not None:
126
+ mod.AsyncCompletions.create = self._original_acreate
127
+ self._original_create = None
128
+ self._original_acreate = None
117
129
 
118
130
  if self._original_embeddings_create is not None:
119
131
  import openai.resources.embeddings as emb_mod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracecast
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: LLM observability SDK — framework-agnostic tracing for AI applications
5
5
  Author: Pedro Castanheira Costa
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes