crewplus 0.2.67__py3-none-any.whl → 0.2.70__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.
- crewplus/services/tracing_manager.py +19 -12
- {crewplus-0.2.67.dist-info → crewplus-0.2.70.dist-info}/METADATA +1 -1
- {crewplus-0.2.67.dist-info → crewplus-0.2.70.dist-info}/RECORD +6 -7
- crewplus/callbacks/run_id_handler.py +0 -99
- {crewplus-0.2.67.dist-info → crewplus-0.2.70.dist-info}/WHEEL +0 -0
- {crewplus-0.2.67.dist-info → crewplus-0.2.70.dist-info}/entry_points.txt +0 -0
- {crewplus-0.2.67.dist-info → crewplus-0.2.70.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,16 +9,11 @@ import logging
|
|
|
9
9
|
try:
|
|
10
10
|
from langfuse.langchain import CallbackHandler as LangfuseCallbackHandler
|
|
11
11
|
from ..callbacks.async_langfuse_handler import AsyncLangfuseCallbackHandler
|
|
12
|
-
# Import the new custom handlers
|
|
13
|
-
from ..callbacks.run_id_handler import RunIdCallbackHandler, AsyncRunIdCallbackHandler
|
|
14
12
|
LANGFUSE_AVAILABLE = True
|
|
15
13
|
except ImportError:
|
|
16
14
|
LANGFUSE_AVAILABLE = False
|
|
17
15
|
LangfuseCallbackHandler = None
|
|
18
16
|
AsyncLangfuseCallbackHandler = None
|
|
19
|
-
# Define dummy classes for the custom handlers to prevent errors if langfuse is not installed
|
|
20
|
-
class RunIdCallbackHandler: pass
|
|
21
|
-
class AsyncRunIdCallbackHandler: pass
|
|
22
17
|
|
|
23
18
|
class TracingContext(Protocol):
|
|
24
19
|
"""
|
|
@@ -89,9 +84,12 @@ class TracingManager:
|
|
|
89
84
|
|
|
90
85
|
def _initialize_langfuse(self):
|
|
91
86
|
"""Initializes the Langfuse handler if it's available and enabled."""
|
|
87
|
+
self.context.logger.debug("Attempting to initialize Langfuse handlers.")
|
|
92
88
|
if not LANGFUSE_AVAILABLE:
|
|
93
89
|
if self.context.enable_tracing is True:
|
|
94
90
|
self.context.logger.warning("Langfuse is not installed; tracing will be disabled. Install with: pip install langfuse")
|
|
91
|
+
else:
|
|
92
|
+
self.context.logger.debug("Langfuse is not installed, skipping handler initialization.")
|
|
95
93
|
return
|
|
96
94
|
|
|
97
95
|
# Determine if Langfuse should be enabled via an explicit flag or
|
|
@@ -103,36 +101,45 @@ class TracingManager:
|
|
|
103
101
|
|
|
104
102
|
if enable_langfuse:
|
|
105
103
|
try:
|
|
106
|
-
# Create and
|
|
107
|
-
|
|
108
|
-
self._sync_handlers.append(
|
|
109
|
-
self._sync_handlers.append(RunIdCallbackHandler())
|
|
104
|
+
# Create both sync and async handlers. We'll pick one at runtime.
|
|
105
|
+
sync_handler = LangfuseCallbackHandler()
|
|
106
|
+
self._sync_handlers.append(sync_handler)
|
|
110
107
|
|
|
111
108
|
if AsyncLangfuseCallbackHandler:
|
|
112
|
-
|
|
113
|
-
self._async_handlers.append(
|
|
109
|
+
async_handler = AsyncLangfuseCallbackHandler()
|
|
110
|
+
self._async_handlers.append(async_handler)
|
|
114
111
|
|
|
115
112
|
self.context.logger.info(f"Langfuse tracing enabled for {self.context.get_model_identifier()}")
|
|
116
113
|
except Exception as e:
|
|
117
|
-
self.context.logger.warning(f"Failed to initialize Langfuse: {e}")
|
|
114
|
+
self.context.logger.warning(f"Failed to initialize Langfuse: {e}", exc_info=True)
|
|
115
|
+
else:
|
|
116
|
+
self.context.logger.info("Langfuse is not enabled, skipping handler initialization.")
|
|
118
117
|
|
|
119
118
|
def _add_callbacks_to_config(self, config: Optional[dict], handlers: List[Any]) -> dict:
|
|
120
119
|
"""A generic helper to add a list of handlers to a config object."""
|
|
121
120
|
if config is None:
|
|
122
121
|
config = {}
|
|
123
122
|
|
|
123
|
+
self.context.logger.debug(f"Adding callbacks to config. Have {len(handlers)} handlers to add.")
|
|
124
|
+
|
|
124
125
|
if not handlers or config.get("metadata", {}).get("tracing_disabled"):
|
|
126
|
+
self.context.logger.debug("No handlers to add or tracing is disabled for this run.")
|
|
125
127
|
return config
|
|
126
128
|
|
|
127
129
|
callbacks = config.get("callbacks")
|
|
128
130
|
|
|
129
131
|
if hasattr(callbacks, 'add_handler') and hasattr(callbacks, 'handlers'):
|
|
132
|
+
# This block is for CallbackManager instances
|
|
133
|
+
self.context.logger.debug(f"Config has a CallbackManager with {len(callbacks.handlers)} existing handlers.")
|
|
130
134
|
for handler in handlers:
|
|
131
135
|
if not any(isinstance(cb, type(handler)) for cb in callbacks.handlers):
|
|
132
136
|
callbacks.add_handler(handler, inherit=True)
|
|
137
|
+
self.context.logger.debug(f"CallbackManager now has {len(callbacks.handlers)} handlers.")
|
|
133
138
|
return config
|
|
134
139
|
|
|
140
|
+
# This block is for simple lists of callbacks
|
|
135
141
|
current_callbacks = callbacks or []
|
|
142
|
+
self.context.logger.debug(f"Config has a list with {len(current_callbacks)} existing callbacks.")
|
|
136
143
|
new_callbacks = list(current_callbacks)
|
|
137
144
|
|
|
138
145
|
for handler in handlers:
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
crewplus-0.2.
|
|
2
|
-
crewplus-0.2.
|
|
3
|
-
crewplus-0.2.
|
|
4
|
-
crewplus-0.2.
|
|
1
|
+
crewplus-0.2.70.dist-info/METADATA,sha256=M2xMdWJbR5BsBLfIGxner83D2vLfE5ui-hmEmhcVMUQ,5424
|
|
2
|
+
crewplus-0.2.70.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
|
3
|
+
crewplus-0.2.70.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
|
4
|
+
crewplus-0.2.70.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
7
|
crewplus/callbacks/async_langfuse_handler.py,sha256=A4uFeLpvOUdc58M7sZoE65_C1V98u0QCvx5jUquM0pM,7006
|
|
8
|
-
crewplus/callbacks/run_id_handler.py,sha256=ZAXGi6-gzOTZVl0xiCeNwjqYwwNd8tB9nocsnsbRSDQ,4371
|
|
9
8
|
crewplus/services/__init__.py,sha256=V1CG8b2NOmRzNgQH7BPl4KVxWSYJH5vfEsW1wVErKNE,375
|
|
10
9
|
crewplus/services/azure_chat_model.py,sha256=iWzJ2GQFSNmwJx-2O5_xKPSB6VVc-7T6bcfFI8_WezA,5521
|
|
11
10
|
crewplus/services/gemini_chat_model.py,sha256=DYqz01H2TIHiCDQesSozVfOsMigno6QGwOtIweg7UHk,40103
|
|
12
11
|
crewplus/services/init_services.py,sha256=tc1ti8Yufo2ixlJpwg8uH0KmoyQ4EqxCOe4uTEWnlRM,2413
|
|
13
12
|
crewplus/services/model_load_balancer.py,sha256=Q9Gx3GrbKworU-Ytxeqp0ggHSgZ1Q6brtTk-nCl4sak,12095
|
|
14
|
-
crewplus/services/tracing_manager.py,sha256=
|
|
13
|
+
crewplus/services/tracing_manager.py,sha256=_C4zYj6o_k5mDWY7vM8UeaVaXp8SqrkvYOb0Jj-y3sY,7566
|
|
15
14
|
crewplus/utils/__init__.py,sha256=2Gk1n5srFJQnFfBuYTxktdtKOVZyNrFcNaZKhXk35Pw,142
|
|
16
15
|
crewplus/utils/schema_action.py,sha256=GDaBoVFQD1rXqrLVSMTfXYW1xcUu7eDcHsn57XBSnIg,422
|
|
17
16
|
crewplus/utils/schema_document_updater.py,sha256=frvffxn2vbi71fHFPoGb9hq7gH2azmmdq17p-Fumnvg,7322
|
|
@@ -23,4 +22,4 @@ docs/GeminiChatModel.md,sha256=zZYyl6RmjZTUsKxxMiC9O4yV70MC4TD-IGUmWhIDBKA,8677
|
|
|
23
22
|
docs/ModelLoadBalancer.md,sha256=aGHES1dcXPz4c7Y8kB5-vsCNJjriH2SWmjBkSGoYKiI,4398
|
|
24
23
|
docs/VDBService.md,sha256=Dw286Rrf_fsi13jyD3Bo4Sy7nZ_G7tYm7d8MZ2j9hxk,9375
|
|
25
24
|
docs/index.md,sha256=3tlc15uR8lzFNM5WjdoZLw0Y9o1P1gwgbEnOdIBspqc,1643
|
|
26
|
-
crewplus-0.2.
|
|
25
|
+
crewplus-0.2.70.dist-info/RECORD,,
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# File: crewplus/callbacks/run_id_handler.py
|
|
2
|
-
|
|
3
|
-
from typing import Any, Dict
|
|
4
|
-
from uuid import UUID
|
|
5
|
-
import logging
|
|
6
|
-
|
|
7
|
-
# Langfuse imports with graceful fallback
|
|
8
|
-
from langfuse.langchain import CallbackHandler as LangfuseCallbackHandler
|
|
9
|
-
from .async_langfuse_handler import AsyncLangfuseCallbackHandler
|
|
10
|
-
from langfuse import get_client
|
|
11
|
-
LANGFUSE_AVAILABLE = True
|
|
12
|
-
|
|
13
|
-
# --- Custom Callback Handlers to capture the run_id ---
|
|
14
|
-
|
|
15
|
-
class RunIdCallbackHandler(LangfuseCallbackHandler):
|
|
16
|
-
"""
|
|
17
|
-
A custom synchronous callback handler that captures the Langchain run_id
|
|
18
|
-
and adds it to the Langfuse trace metadata. It also stores the mapping
|
|
19
|
-
between the run_id and the generated trace_id.
|
|
20
|
-
"""
|
|
21
|
-
def __init__(self, *args, **kwargs):
|
|
22
|
-
super().__init__(*args, **kwargs)
|
|
23
|
-
self.run_trace_map = {}
|
|
24
|
-
# Use a named logger for better context
|
|
25
|
-
self.logger = logging.getLogger(__name__)
|
|
26
|
-
self.logger.info("RunIdCallbackHandler initialized.")
|
|
27
|
-
|
|
28
|
-
def on_chain_start(
|
|
29
|
-
self,
|
|
30
|
-
serialized: Dict[str, Any],
|
|
31
|
-
inputs: Dict[str, Any],
|
|
32
|
-
run_id: UUID,
|
|
33
|
-
**kwargs: Any,
|
|
34
|
-
) -> Any:
|
|
35
|
-
self.logger.debug(f"on_chain_start triggered for run_id: {run_id}")
|
|
36
|
-
# First, let the base handler do its work, which includes creating the trace
|
|
37
|
-
run = super().on_chain_start(serialized, inputs, run_id, **kwargs)
|
|
38
|
-
self.logger.debug(f"Base handler's on_chain_start completed. Current trace_id: {self.last_trace_id}")
|
|
39
|
-
|
|
40
|
-
try:
|
|
41
|
-
# The base handler sets `self.last_trace_id` when a trace is created
|
|
42
|
-
if self.last_trace_id:
|
|
43
|
-
self.run_trace_map[str(run_id)] = self.last_trace_id
|
|
44
|
-
self.logger.info(f"Mapping run_id '{run_id}' to trace_id '{self.last_trace_id}'.")
|
|
45
|
-
|
|
46
|
-
# Then, update the created trace with the run_id as metadata
|
|
47
|
-
langfuse_client = get_client()
|
|
48
|
-
langfuse_client.update_current_trace(
|
|
49
|
-
metadata={"langchain_run_id": str(run_id)}
|
|
50
|
-
)
|
|
51
|
-
self.logger.info(f"Successfully updated trace '{self.last_trace_id}' with metadata for run_id '{run_id}'.")
|
|
52
|
-
else:
|
|
53
|
-
self.logger.warning(f"Could not find 'last_trace_id' for run_id '{run_id}'. Metadata will not be updated.")
|
|
54
|
-
|
|
55
|
-
except Exception as e:
|
|
56
|
-
self.logger.error(f"Failed to process run_id '{run_id}' in RunIdCallbackHandler: {e}", exc_info=True)
|
|
57
|
-
|
|
58
|
-
return run
|
|
59
|
-
|
|
60
|
-
class AsyncRunIdCallbackHandler(AsyncLangfuseCallbackHandler):
|
|
61
|
-
"""
|
|
62
|
-
A custom asynchronous callback handler that captures the Langchain run_id
|
|
63
|
-
and adds it to the Langfuse trace metadata.
|
|
64
|
-
"""
|
|
65
|
-
def __init__(self, *args, **kwargs):
|
|
66
|
-
super().__init__(*args, **kwargs)
|
|
67
|
-
self.run_trace_map = {}
|
|
68
|
-
self.logger = logging.getLogger(__name__)
|
|
69
|
-
self.logger.info("AsyncRunIdCallbackHandler initialized.")
|
|
70
|
-
|
|
71
|
-
async def on_chain_start(
|
|
72
|
-
self,
|
|
73
|
-
serialized: Dict[str, Any],
|
|
74
|
-
inputs: Dict[str, Any],
|
|
75
|
-
run_id: UUID,
|
|
76
|
-
**kwargs: Any,
|
|
77
|
-
) -> Any:
|
|
78
|
-
self.logger.debug(f"Async on_chain_start triggered for run_id: {run_id}")
|
|
79
|
-
# First, let the base handler do its work
|
|
80
|
-
run = await super().on_chain_start(serialized, inputs, run_id, **kwargs)
|
|
81
|
-
self.logger.debug(f"Async base handler's on_chain_start completed. Current trace_id: {self.last_trace_id}")
|
|
82
|
-
|
|
83
|
-
try:
|
|
84
|
-
if self.last_trace_id:
|
|
85
|
-
self.run_trace_map[str(run_id)] = self.last_trace_id
|
|
86
|
-
self.logger.info(f"Async: Mapping run_id '{run_id}' to trace_id '{self.last_trace_id}'.")
|
|
87
|
-
|
|
88
|
-
langfuse_client = get_client()
|
|
89
|
-
langfuse_client.update_current_trace(
|
|
90
|
-
metadata={"langchain_run_id": str(run_id)}
|
|
91
|
-
)
|
|
92
|
-
self.logger.info(f"Async: Successfully updated trace '{self.last_trace_id}' with metadata for run_id '{run_id}'.")
|
|
93
|
-
else:
|
|
94
|
-
self.logger.warning(f"Async: Could not find 'last_trace_id' for run_id '{run_id}'. Metadata will not be updated.")
|
|
95
|
-
|
|
96
|
-
except Exception as e:
|
|
97
|
-
self.logger.error(f"Async: Failed to process run_id '{run_id}' in AsyncRunIdCallbackHandler: {e}", exc_info=True)
|
|
98
|
-
|
|
99
|
-
return run
|
|
File without changes
|
|
File without changes
|
|
File without changes
|