crewplus 0.2.71__py3-none-any.whl → 0.2.73__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 crewplus might be problematic. Click here for more details.

@@ -42,10 +42,14 @@ class AsyncLangfuseCallbackHandler(AsyncCallbackHandler):
42
42
  Wraps the synchronous LangfuseCallbackHandler to make it fully compatible with
43
43
  LangChain's async methods by handling all relevant events.
44
44
  """
45
- def __init__(self, *args: Any, **kwargs: Any):
45
+ def __init__(self, sync_handler: Optional[LangfuseCallbackHandler] = None, *args: Any, **kwargs: Any):
46
46
  if not LANGFUSE_AVAILABLE:
47
47
  raise ImportError("Langfuse is not available. Please install it with 'pip install langfuse'")
48
- self.sync_handler = LangfuseCallbackHandler(*args, **kwargs)
48
+
49
+ if sync_handler:
50
+ self.sync_handler = sync_handler
51
+ else:
52
+ self.sync_handler = LangfuseCallbackHandler(*args, **kwargs)
49
53
 
50
54
  def __getattr__(self, name: str) -> Any:
51
55
  return getattr(self.sync_handler, name)
@@ -1,6 +1,6 @@
1
1
  # File: crewplus/services/tracing_manager.py
2
2
 
3
- from typing import Any, Optional, List, Protocol
3
+ from typing import Any, Optional, List, Protocol, Dict
4
4
  import os
5
5
  import logging
6
6
 
@@ -9,11 +9,14 @@ import logging
9
9
  try:
10
10
  from langfuse.langchain import CallbackHandler as LangfuseCallbackHandler
11
11
  from ..callbacks.async_langfuse_handler import AsyncLangfuseCallbackHandler
12
+ from ..utils.tracing_util import get_langfuse_handler, get_async_langfuse_handler
12
13
  LANGFUSE_AVAILABLE = True
13
14
  except ImportError:
14
15
  LANGFUSE_AVAILABLE = False
15
16
  LangfuseCallbackHandler = None
16
17
  AsyncLangfuseCallbackHandler = None
18
+ get_langfuse_handler = None
19
+ get_async_langfuse_handler = None
17
20
 
18
21
  class TracingContext(Protocol):
19
22
  """
@@ -102,11 +105,11 @@ class TracingManager:
102
105
  if enable_langfuse:
103
106
  try:
104
107
  # Create both sync and async handlers. We'll pick one at runtime.
105
- sync_handler = LangfuseCallbackHandler()
108
+ sync_handler = get_langfuse_handler()
106
109
  self._sync_handlers.append(sync_handler)
107
110
 
108
111
  if AsyncLangfuseCallbackHandler:
109
- async_handler = AsyncLangfuseCallbackHandler()
112
+ async_handler = get_async_langfuse_handler()
110
113
  self._async_handlers.append(async_handler)
111
114
 
112
115
  self.context.logger.info(f"Langfuse tracing enabled for {self.context.get_model_identifier()}")
@@ -115,7 +118,7 @@ class TracingManager:
115
118
  else:
116
119
  self.context.logger.info("Langfuse is not enabled, skipping handler initialization.")
117
120
 
118
- def _add_callbacks_to_config(self, config: Optional[dict], handlers: List[Any]) -> dict:
121
+ def add_callbacks_to_config(self, config: Optional[dict], handlers: List[Any]) -> dict:
119
122
  """A generic helper to add a list of handlers to a config object."""
120
123
  if config is None:
121
124
  config = {}
@@ -154,10 +157,26 @@ class TracingManager:
154
157
 
155
158
  return config
156
159
 
157
- def add_sync_callbacks_to_config(self, config: Optional[dict]) -> dict:
158
- """Adds synchronous tracing handlers to the request configuration."""
159
- return self._add_callbacks_to_config(config, self._sync_handlers)
160
+ def add_sync_callbacks_to_config(self, config: Optional[dict], handlers: Optional[List[Any]] = None) -> dict:
161
+ """
162
+ Adds synchronous tracing handlers to the request configuration.
163
+
164
+ Args:
165
+ config: The configuration dictionary to which callbacks will be added.
166
+ handlers: An optional list of handlers to add. If not provided,
167
+ the manager's default synchronous handlers are used.
168
+ """
169
+ handlers_to_add = self._sync_handlers if handlers is None else handlers
170
+ return self.add_callbacks_to_config(config, handlers_to_add)
160
171
 
161
- def add_async_callbacks_to_config(self, config: Optional[dict]) -> dict:
162
- """Adds asynchronous tracing handlers to the request configuration."""
163
- return self._add_callbacks_to_config(config, self._async_handlers)
172
+ def add_async_callbacks_to_config(self, config: Optional[dict], handlers: Optional[List[Any]] = None) -> dict:
173
+ """
174
+ Adds asynchronous tracing handlers to the request configuration.
175
+
176
+ Args:
177
+ config: The configuration dictionary to which callbacks will be added.
178
+ handlers: An optional list of handlers to add. If not provided,
179
+ the manager's default asynchronous handlers are used.
180
+ """
181
+ handlers_to_add = self._async_handlers if handlers is None else handlers
182
+ return self.add_callbacks_to_config(config, handlers_to_add)
@@ -0,0 +1,55 @@
1
+ from typing import Dict, Any, Optional
2
+ from langchain_core.runnables import RunnableConfig
3
+ from langfuse.langchain import CallbackHandler as LangfuseCallbackHandler
4
+ from ..callbacks.async_langfuse_handler import AsyncLangfuseCallbackHandler
5
+
6
+ # Singleton holder for the Langfuse handler to avoid multiple instances per run
7
+ _LANGFUSE_HANDLER: Optional[LangfuseCallbackHandler] = None
8
+ _ASYNC_LANGFUSE_HANDLER: Optional[AsyncLangfuseCallbackHandler] = None
9
+
10
+ def _get_langfuse_handler() -> LangfuseCallbackHandler:
11
+ global _LANGFUSE_HANDLER
12
+ if _LANGFUSE_HANDLER is None:
13
+ _LANGFUSE_HANDLER = LangfuseCallbackHandler()
14
+ return _LANGFUSE_HANDLER
15
+
16
+ def get_langfuse_handler() -> LangfuseCallbackHandler:
17
+ return _get_langfuse_handler()
18
+
19
+ def get_async_langfuse_handler() -> "AsyncLangfuseCallbackHandler":
20
+ """
21
+ Returns a singleton instance of the async Langfuse handler, ensuring it
22
+ shares the same underlying synchronous Langfuse handler singleton.
23
+ """
24
+ global _ASYNC_LANGFUSE_HANDLER
25
+ if _ASYNC_LANGFUSE_HANDLER is None:
26
+ sync_handler = get_langfuse_handler()
27
+ _ASYNC_LANGFUSE_HANDLER = AsyncLangfuseCallbackHandler(sync_handler=sync_handler)
28
+ return _ASYNC_LANGFUSE_HANDLER
29
+
30
+ def prepare_trace_config(context: Dict[str, Any]) -> RunnableConfig:
31
+ """
32
+ Prepares a minimal RunnableConfig for tracing, primarily for Langfuse.
33
+
34
+ - Creates a new config containing only tracing-related information.
35
+ - Extracts 'trace_metadata' from the context's 'configurable' dict
36
+ and uses it as the 'metadata' for the new trace config.
37
+ - Adds a singleton Langfuse callback handler.
38
+ """
39
+ # The full config is passed in the 'config' key of the context
40
+ # Start with a copy of the existing config from the graph to preserve its state
41
+ run_config = context.get("config", {}).copy()
42
+
43
+ # Extract trace_metadata from the 'configurable' part of the full config
44
+ trace_metadata = run_config.get("trace_metadata", {})
45
+ if not trace_metadata:
46
+ trace_metadata = run_config.get("configurable", {}).get("trace_metadata", {})
47
+
48
+ # If trace_metadata exists, merge all its fields into the main metadata key
49
+ if trace_metadata and isinstance(trace_metadata, dict):
50
+ if "metadata" not in run_config:
51
+ run_config["metadata"] = {}
52
+ run_config["metadata"].update(trace_metadata)
53
+
54
+ return run_config
55
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crewplus
3
- Version: 0.2.71
3
+ Version: 0.2.73
4
4
  Summary: Base services for CrewPlus AI applications
5
5
  Author-Email: Tim Liu <tim@opsmateai.com>
6
6
  License: MIT
@@ -1,19 +1,20 @@
1
- crewplus-0.2.71.dist-info/METADATA,sha256=x45o-KC-K6zW8OIsL3eEwcS-mQ2wupMQYHVo5JANcLs,5424
2
- crewplus-0.2.71.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- crewplus-0.2.71.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- crewplus-0.2.71.dist-info/licenses/LICENSE,sha256=2_NHSHRTKB_cTcT_GXgcenOCtIZku8j343mOgAguTfc,1087
1
+ crewplus-0.2.73.dist-info/METADATA,sha256=TK-9vndgc42n3Ovj05JoC5ZkeVVrffOcwC4HloEEyXc,5424
2
+ crewplus-0.2.73.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ crewplus-0.2.73.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ crewplus-0.2.73.dist-info/licenses/LICENSE,sha256=2_NHSHRTKB_cTcT_GXgcenOCtIZku8j343mOgAguTfc,1087
5
5
  crewplus/__init__.py,sha256=m46HkZL1Y4toD619NL47Sn2Qe084WFFSFD7e6VoYKZc,284
6
6
  crewplus/callbacks/__init__.py,sha256=YG7ieeb91qEjp1zF0-inEN7mjZ7yT_D2yzdWFT8Z1Ws,63
7
- crewplus/callbacks/async_langfuse_handler.py,sha256=A4uFeLpvOUdc58M7sZoE65_C1V98u0QCvx5jUquM0pM,7006
7
+ crewplus/callbacks/async_langfuse_handler.py,sha256=8_p7ctgcmDNQgF5vOqA47I0x-3GWsm7zioZcZHgedZk,7163
8
8
  crewplus/services/__init__.py,sha256=V1CG8b2NOmRzNgQH7BPl4KVxWSYJH5vfEsW1wVErKNE,375
9
9
  crewplus/services/azure_chat_model.py,sha256=iWzJ2GQFSNmwJx-2O5_xKPSB6VVc-7T6bcfFI8_WezA,5521
10
10
  crewplus/services/gemini_chat_model.py,sha256=DYqz01H2TIHiCDQesSozVfOsMigno6QGwOtIweg7UHk,40103
11
11
  crewplus/services/init_services.py,sha256=tc1ti8Yufo2ixlJpwg8uH0KmoyQ4EqxCOe4uTEWnlRM,2413
12
12
  crewplus/services/model_load_balancer.py,sha256=Q9Gx3GrbKworU-Ytxeqp0ggHSgZ1Q6brtTk-nCl4sak,12095
13
- crewplus/services/tracing_manager.py,sha256=_C4zYj6o_k5mDWY7vM8UeaVaXp8SqrkvYOb0Jj-y3sY,7566
13
+ crewplus/services/tracing_manager.py,sha256=pwNFeA77vnoZMh_AUOnK5TvAaPOOLg5oDnVOe1yUa9A,8502
14
14
  crewplus/utils/__init__.py,sha256=2Gk1n5srFJQnFfBuYTxktdtKOVZyNrFcNaZKhXk35Pw,142
15
15
  crewplus/utils/schema_action.py,sha256=GDaBoVFQD1rXqrLVSMTfXYW1xcUu7eDcHsn57XBSnIg,422
16
16
  crewplus/utils/schema_document_updater.py,sha256=frvffxn2vbi71fHFPoGb9hq7gH2azmmdq17p-Fumnvg,7322
17
+ crewplus/utils/tracing_util.py,sha256=ew5VwjTKcY88P2sveIlGqmsNFR5OJ-DjKAHKQzBoTyE,2449
17
18
  crewplus/vectorstores/milvus/__init__.py,sha256=OeYv2rdyG7tcREIjBJPyt2TbE54NvyeRoWMe7LwopRE,245
18
19
  crewplus/vectorstores/milvus/milvus_schema_manager.py,sha256=-QRav-hzu-XWeJ_yKUMolal_EyMUspSg-nvh5sqlrlQ,11442
19
20
  crewplus/vectorstores/milvus/schema_milvus.py,sha256=wwNpfqsKS0xeozZES40IvB0iNwUtpCall_7Hkg0dL1g,27223
@@ -22,4 +23,4 @@ docs/GeminiChatModel.md,sha256=zZYyl6RmjZTUsKxxMiC9O4yV70MC4TD-IGUmWhIDBKA,8677
22
23
  docs/ModelLoadBalancer.md,sha256=aGHES1dcXPz4c7Y8kB5-vsCNJjriH2SWmjBkSGoYKiI,4398
23
24
  docs/VDBService.md,sha256=Dw286Rrf_fsi13jyD3Bo4Sy7nZ_G7tYm7d8MZ2j9hxk,9375
24
25
  docs/index.md,sha256=3tlc15uR8lzFNM5WjdoZLw0Y9o1P1gwgbEnOdIBspqc,1643
25
- crewplus-0.2.71.dist-info/RECORD,,
26
+ crewplus-0.2.73.dist-info/RECORD,,