crewplus 0.2.42__py3-none-any.whl → 0.2.44__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.

@@ -50,10 +50,18 @@ class AsyncLangfuseCallbackHandler(AsyncCallbackHandler):
50
50
  async def on_llm_start(
51
51
  self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
52
52
  ) -> None:
53
+ # --- DEBUGGING: Inspect the arguments from LangChain ---
54
+ print("--- [DEBUG] AsyncLangfuseCallbackHandler.on_llm_start ---")
55
+ print(f"Received prompts type: {type(prompts)}")
56
+ print(f"Received prompts value: {prompts!r}") # Using !r to see quotes if it's a string
57
+ print("----------------------------------------------------------")
58
+ # --- END DEBUGGING ---
59
+
53
60
  # WORKAROUND: LangChain's async implementation can sometimes pass a raw
54
61
  # string for prompts instead of a list. We wrap it in a list to ensure
55
62
  # compatibility with the synchronous handler.
56
63
  corrected_prompts = prompts if isinstance(prompts, list) else [prompts]
64
+
57
65
  await asyncio.to_thread(
58
66
  self.sync_handler.on_llm_start, serialized, corrected_prompts, **kwargs
59
67
  )
@@ -5,7 +5,6 @@ from typing import Any, Optional
5
5
  from langchain_openai.chat_models.azure import AzureChatOpenAI
6
6
  from pydantic import Field
7
7
  from .tracing_manager import TracingManager, TracingContext
8
- from ..callbacks.async_langfuse_handler import async_context
9
8
 
10
9
  class TracedAzureChatOpenAI(AzureChatOpenAI):
11
10
  """
@@ -103,13 +102,12 @@ class TracedAzureChatOpenAI(AzureChatOpenAI):
103
102
  return f"{self.__class__.__name__} (deployment='{self.deployment_name}')"
104
103
 
105
104
  def invoke(self, input, config=None, **kwargs):
106
- config = self._tracing_manager.add_callbacks_to_config(config)
105
+ config = self._tracing_manager.add_sync_callbacks_to_config(config)
107
106
  return super().invoke(input, config=config, **kwargs)
108
107
 
109
108
  async def ainvoke(self, input, config=None, **kwargs):
110
- with async_context():
111
- config = self._tracing_manager.add_callbacks_to_config(config)
112
- return await super().ainvoke(input, config=config, **kwargs)
109
+ config = self._tracing_manager.add_async_callbacks_to_config(config)
110
+ return await super().ainvoke(input, config=config, **kwargs)
113
111
 
114
112
  def stream(self, input, config=None, **kwargs):
115
113
  # Add stream_options to get usage data for Langfuse
@@ -117,7 +115,7 @@ class TracedAzureChatOpenAI(AzureChatOpenAI):
117
115
  stream_options["include_usage"] = True
118
116
  kwargs["stream_options"] = stream_options
119
117
 
120
- config = self._tracing_manager.add_callbacks_to_config(config)
118
+ config = self._tracing_manager.add_sync_callbacks_to_config(config)
121
119
  yield from super().stream(input, config=config, **kwargs)
122
120
 
123
121
  async def astream(self, input, config=None, **kwargs) :
@@ -126,7 +124,6 @@ class TracedAzureChatOpenAI(AzureChatOpenAI):
126
124
  stream_options["include_usage"] = True
127
125
  kwargs["stream_options"] = stream_options
128
126
 
129
- with async_context():
130
- config = self._tracing_manager.add_callbacks_to_config(config)
131
- async for chunk in super().astream(input, config=config, **kwargs):
132
- yield chunk
127
+ config = self._tracing_manager.add_async_callbacks_to_config(config)
128
+ async for chunk in super().astream(input, config=config, **kwargs):
129
+ yield chunk
@@ -8,13 +8,12 @@ import logging
8
8
  # even if the langfuse library is not installed.
9
9
  try:
10
10
  from langfuse.langchain import CallbackHandler as LangfuseCallbackHandler
11
- from ..callbacks.async_langfuse_handler import AsyncLangfuseCallbackHandler, in_async_context
11
+ from ..callbacks.async_langfuse_handler import AsyncLangfuseCallbackHandler
12
12
  LANGFUSE_AVAILABLE = True
13
13
  except ImportError:
14
14
  LANGFUSE_AVAILABLE = False
15
15
  LangfuseCallbackHandler = None
16
16
  AsyncLangfuseCallbackHandler = None
17
- in_async_context = None
18
17
 
19
18
  class TracingContext(Protocol):
20
19
  """
@@ -111,42 +110,22 @@ class TracingManager:
111
110
  except Exception as e:
112
111
  self.context.logger.warning(f"Failed to initialize Langfuse: {e}")
113
112
 
114
- def add_callbacks_to_config(self, config: Optional[dict]) -> dict:
115
- """
116
- Adds all registered tracing handlers to the request configuration.
117
-
118
- This method is robust and handles three scenarios for the 'callbacks' key:
119
- 1. A list of callbacks.
120
- 2. A LangChain CallbackManager instance.
121
- 3. None or a missing key.
122
-
123
- Args:
124
- config: The request configuration dictionary from a LangChain call.
125
-
126
- Returns:
127
- The updated configuration dictionary with tracing callbacks added.
128
- """
113
+ def _add_callbacks_to_config(self, config: Optional[dict], handlers: List[Any]) -> dict:
114
+ """A generic helper to add a list of handlers to a config object."""
129
115
  if config is None:
130
116
  config = {}
131
117
 
132
- # Decide which handlers to use based on the async context flag.
133
- is_async = in_async_context.get() if in_async_context else False
134
- handlers = self._async_handlers if is_async else self._sync_handlers
135
-
136
- # Respect a global disable flag for this specific call.
137
118
  if not handlers or config.get("metadata", {}).get("tracing_disabled"):
138
119
  return config
139
120
 
140
121
  callbacks = config.get("callbacks")
141
122
 
142
- # Case 1: The 'callbacks' key holds a CallbackManager instance
143
123
  if hasattr(callbacks, 'add_handler') and hasattr(callbacks, 'handlers'):
144
124
  for handler in handlers:
145
125
  if not any(isinstance(cb, type(handler)) for cb in callbacks.handlers):
146
126
  callbacks.add_handler(handler, inherit=True)
147
- return config # Return the original, now-mutated config
127
+ return config
148
128
 
149
- # Case 2: The 'callbacks' key holds a list or is None
150
129
  current_callbacks = callbacks or []
151
130
  new_callbacks = list(current_callbacks)
152
131
 
@@ -161,3 +140,11 @@ class TracingManager:
161
140
  return {**config, "callbacks": new_callbacks}
162
141
 
163
142
  return config
143
+
144
+ def add_sync_callbacks_to_config(self, config: Optional[dict]) -> dict:
145
+ """Adds synchronous tracing handlers to the request configuration."""
146
+ return self._add_callbacks_to_config(config, self._sync_handlers)
147
+
148
+ def add_async_callbacks_to_config(self, config: Optional[dict]) -> dict:
149
+ """Adds asynchronous tracing handlers to the request configuration."""
150
+ return self._add_callbacks_to_config(config, self._async_handlers)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crewplus
3
- Version: 0.2.42
3
+ Version: 0.2.44
4
4
  Summary: Base services for CrewPlus AI applications
5
5
  Author-Email: Tim Liu <tim@opsmateai.com>
6
6
  License: MIT
@@ -1,16 +1,16 @@
1
- crewplus-0.2.42.dist-info/METADATA,sha256=NMEudKtv137fmfM09RfvDIhT0y3ha-DHJuxG8GlOqzI,5362
2
- crewplus-0.2.42.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- crewplus-0.2.42.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- crewplus-0.2.42.dist-info/licenses/LICENSE,sha256=2_NHSHRTKB_cTcT_GXgcenOCtIZku8j343mOgAguTfc,1087
1
+ crewplus-0.2.44.dist-info/METADATA,sha256=KdBsfThzg0wjMW0ydjEsKw_Kp5c-nX76GQ721K4FOHY,5362
2
+ crewplus-0.2.44.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ crewplus-0.2.44.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ crewplus-0.2.44.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=YZhwyLTQ3IcL9K9cAfNQxDNZYY365mIPuzKTM1vtn-Y,4194
7
+ crewplus/callbacks/async_langfuse_handler.py,sha256=XnHpQ-sqcUCb6BCrE_JgldtTbaV61lH9aJnfy_IUp9Y,4614
8
8
  crewplus/services/__init__.py,sha256=V1CG8b2NOmRzNgQH7BPl4KVxWSYJH5vfEsW1wVErKNE,375
9
- crewplus/services/azure_chat_model.py,sha256=LXTd1g6OBV-YEaGokVNMddd1P5BU8nfV4k5tG_GcH04,5643
9
+ crewplus/services/azure_chat_model.py,sha256=iWzJ2GQFSNmwJx-2O5_xKPSB6VVc-7T6bcfFI8_WezA,5521
10
10
  crewplus/services/gemini_chat_model.py,sha256=VsOB_st1qRmDkwLXzo-gCShhUsZHpk0V-G-ulQXGN3g,40081
11
11
  crewplus/services/init_services.py,sha256=7oZ1GmesK32EDB_DYnTzW17MEpXjXK41_U_1pmqu_m4,2183
12
12
  crewplus/services/model_load_balancer.py,sha256=Q9Gx3GrbKworU-Ytxeqp0ggHSgZ1Q6brtTk-nCl4sak,12095
13
- crewplus/services/tracing_manager.py,sha256=vT-7zerq6v0x-cwEBWAsB9NHdul4mPDnI60azcngTr8,7058
13
+ crewplus/services/tracing_manager.py,sha256=0KR-F0BKYEMdADANWofFZH9D9jcWDHzDICUE7nDhzJc,6579
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
@@ -22,4 +22,4 @@ docs/GeminiChatModel.md,sha256=zZYyl6RmjZTUsKxxMiC9O4yV70MC4TD-IGUmWhIDBKA,8677
22
22
  docs/ModelLoadBalancer.md,sha256=aGHES1dcXPz4c7Y8kB5-vsCNJjriH2SWmjBkSGoYKiI,4398
23
23
  docs/VDBService.md,sha256=Dw286Rrf_fsi13jyD3Bo4Sy7nZ_G7tYm7d8MZ2j9hxk,9375
24
24
  docs/index.md,sha256=3tlc15uR8lzFNM5WjdoZLw0Y9o1P1gwgbEnOdIBspqc,1643
25
- crewplus-0.2.42.dist-info/RECORD,,
25
+ crewplus-0.2.44.dist-info/RECORD,,