mermaid-trace 0.6.0.post0__py3-none-any.whl → 0.6.1.post0__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.
@@ -5,7 +5,7 @@ This module provides a LangChain Callback Handler that allows you to automatical
5
5
  generate Mermaid sequence diagrams for your LangChain chains, LLM calls, and tool usage.
6
6
  """
7
7
 
8
- from typing import Any, Dict, List, Optional, TYPE_CHECKING
8
+ from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
9
9
  import uuid
10
10
 
11
11
  from ..core.events import FlowEvent
@@ -15,30 +15,35 @@ from ..core.decorators import get_flow_logger
15
15
  if TYPE_CHECKING:
16
16
  from langchain_core.callbacks import BaseCallbackHandler
17
17
  from langchain_core.outputs import LLMResult
18
+ from langchain_core.agents import AgentAction, AgentFinish
19
+ from langchain_core.documents import Document
18
20
  else:
19
21
  try:
20
22
  from langchain_core.callbacks import BaseCallbackHandler
21
23
  from langchain_core.outputs import LLMResult
24
+ from langchain_core.agents import AgentAction, AgentFinish
25
+ from langchain_core.documents import Document
22
26
  except ImportError:
23
27
  BaseCallbackHandler = object
24
28
  LLMResult = Any
29
+ AgentAction = Any
30
+ AgentFinish = Any
31
+ Document = Any
25
32
 
26
33
 
27
34
  class MermaidTraceCallbackHandler(BaseCallbackHandler):
28
- """
29
- LangChain Callback Handler that records execution flow as Mermaid sequence diagrams.
35
+ """LangChain Callback Handler that records execution flow as Mermaid sequence diagrams.
30
36
 
31
- This handler intercepts LangChain events (Chain, LLM, Tool) and logs them as
37
+ This handler intercepts LangChain events (Chain, LLM, Tool, Agent) and logs them as
32
38
  FlowEvents, which are then processed by MermaidTrace to generate diagrams.
33
39
  """
34
40
 
35
41
  def __init__(self, host_name: str = "LangChain"):
36
- """
37
- Initialize the callback handler.
42
+ """Initialize the callback handler.
38
43
 
39
44
  Args:
40
- host_name (str): The name of the host participant in the diagram.
41
- Defaults to "LangChain".
45
+ host_name: The name of the host participant in the diagram.
46
+ Defaults to "LangChain".
42
47
  """
43
48
  if BaseCallbackHandler is object:
44
49
  raise ImportError(
@@ -50,6 +55,7 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
50
55
  self._participant_stack: List[str] = []
51
56
 
52
57
  def _get_current_source(self) -> str:
58
+ """Get the current source participant from stack or context."""
53
59
  if self._participant_stack:
54
60
  return self._participant_stack[-1]
55
61
  return str(LogContext.get("current_participant", self.host_name))
@@ -58,6 +64,11 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
58
64
  self,
59
65
  serialized: Optional[Dict[str, Any]],
60
66
  inputs: Dict[str, Any],
67
+ *,
68
+ run_id: Any = None,
69
+ parent_run_id: Any = None,
70
+ tags: Optional[List[str]] = None,
71
+ metadata: Optional[Dict[str, Any]] = None,
61
72
  **kwargs: Any,
62
73
  ) -> None:
63
74
  """Run when chain starts running."""
@@ -81,7 +92,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
81
92
  )
82
93
  self._participant_stack.append(target)
83
94
 
84
- def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> None:
95
+ def on_chain_end(
96
+ self,
97
+ outputs: Dict[str, Any],
98
+ *,
99
+ run_id: Any = None,
100
+ parent_run_id: Any = None,
101
+ **kwargs: Any,
102
+ ) -> None:
85
103
  """Run when chain ends running."""
86
104
  if not self._participant_stack:
87
105
  return
@@ -103,7 +121,15 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
103
121
  )
104
122
 
105
123
  def on_llm_start(
106
- self, serialized: Optional[Dict[str, Any]], prompts: List[str], **kwargs: Any
124
+ self,
125
+ serialized: Optional[Dict[str, Any]],
126
+ prompts: List[str],
127
+ *,
128
+ run_id: Any = None,
129
+ parent_run_id: Any = None,
130
+ tags: Optional[List[str]] = None,
131
+ metadata: Optional[Dict[str, Any]] = None,
132
+ **kwargs: Any,
107
133
  ) -> None:
108
134
  """Run when LLM starts running."""
109
135
  target = (serialized.get("name") if serialized else None) or "LLM"
@@ -126,6 +152,11 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
126
152
  self,
127
153
  serialized: Optional[Dict[str, Any]],
128
154
  messages: List[List[Any]],
155
+ *,
156
+ run_id: Any = None,
157
+ parent_run_id: Any = None,
158
+ tags: Optional[List[str]] = None,
159
+ metadata: Optional[Dict[str, Any]] = None,
129
160
  **kwargs: Any,
130
161
  ) -> None:
131
162
  """Run when Chat Model starts running."""
@@ -145,7 +176,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
145
176
  )
146
177
  self._participant_stack.append(target)
147
178
 
148
- def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
179
+ def on_llm_end(
180
+ self,
181
+ response: LLMResult,
182
+ *,
183
+ run_id: Any = None,
184
+ parent_run_id: Any = None,
185
+ **kwargs: Any,
186
+ ) -> None:
149
187
  """Run when LLM ends running."""
150
188
  if not self._participant_stack:
151
189
  return
@@ -166,7 +204,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
166
204
  f"{source} -> {target}: {event.action}", extra={"flow_event": event}
167
205
  )
168
206
 
169
- def on_llm_error(self, error: BaseException, **kwargs: Any) -> None:
207
+ def on_llm_error(
208
+ self,
209
+ error: BaseException,
210
+ *,
211
+ run_id: Any = None,
212
+ parent_run_id: Any = None,
213
+ **kwargs: Any,
214
+ ) -> None:
170
215
  """Run when LLM errors."""
171
216
  if not self._participant_stack:
172
217
  return
@@ -190,6 +235,11 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
190
235
  self,
191
236
  serialized: Optional[Dict[str, Any]],
192
237
  query: str,
238
+ *,
239
+ run_id: Any = None,
240
+ parent_run_id: Any = None,
241
+ tags: Optional[List[str]] = None,
242
+ metadata: Optional[Dict[str, Any]] = None,
193
243
  **kwargs: Any,
194
244
  ) -> None:
195
245
  """Run when Retriever starts running."""
@@ -209,7 +259,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
209
259
  )
210
260
  self._participant_stack.append(target)
211
261
 
212
- def on_retriever_end(self, documents: List[Any], **kwargs: Any) -> Any: # type: ignore[override]
262
+ def on_retriever_end(
263
+ self,
264
+ documents: Sequence[Document],
265
+ *,
266
+ run_id: Any = None,
267
+ parent_run_id: Any = None,
268
+ **kwargs: Any,
269
+ ) -> Any:
213
270
  """Run when Retriever ends running."""
214
271
  if not self._participant_stack:
215
272
  return
@@ -231,7 +288,15 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
231
288
  )
232
289
 
233
290
  def on_tool_start(
234
- self, serialized: Optional[Dict[str, Any]], input_str: str, **kwargs: Any
291
+ self,
292
+ serialized: Optional[Dict[str, Any]],
293
+ input_str: str,
294
+ *,
295
+ run_id: Any = None,
296
+ parent_run_id: Any = None,
297
+ tags: Optional[List[str]] = None,
298
+ metadata: Optional[Dict[str, Any]] = None,
299
+ **kwargs: Any,
235
300
  ) -> None:
236
301
  """Run when tool starts running."""
237
302
  target = (serialized.get("name") if serialized else None) or "Tool"
@@ -250,7 +315,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
250
315
  )
251
316
  self._participant_stack.append(target)
252
317
 
253
- def on_tool_end(self, output: Any, **kwargs: Any) -> None:
318
+ def on_tool_end(
319
+ self,
320
+ output: Any,
321
+ *,
322
+ run_id: Any = None,
323
+ parent_run_id: Any = None,
324
+ **kwargs: Any,
325
+ ) -> None:
254
326
  """Run when tool ends running."""
255
327
  if not self._participant_stack:
256
328
  return
@@ -271,7 +343,63 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
271
343
  f"{target} -> {source}: {event.action}", extra={"flow_event": event}
272
344
  )
273
345
 
274
- def on_chain_error(self, error: BaseException, **kwargs: Any) -> None:
346
+ def on_agent_action(
347
+ self,
348
+ action: AgentAction,
349
+ *,
350
+ run_id: Any = None,
351
+ parent_run_id: Any = None,
352
+ **kwargs: Any,
353
+ ) -> Any:
354
+ """Run on agent action."""
355
+ target = action.tool
356
+ source = self._get_current_source()
357
+
358
+ event = FlowEvent(
359
+ source=source,
360
+ target=target,
361
+ action="Agent Action",
362
+ message=f"Decided to use: {target}",
363
+ trace_id=LogContext.get("trace_id", str(uuid.uuid4())),
364
+ params=str(action.tool_input),
365
+ )
366
+ self.logger.info(
367
+ f"{source} -> {target}: {event.action}", extra={"flow_event": event}
368
+ )
369
+
370
+ def on_agent_finish(
371
+ self,
372
+ finish: AgentFinish,
373
+ *,
374
+ run_id: Any = None,
375
+ parent_run_id: Any = None,
376
+ **kwargs: Any,
377
+ ) -> Any:
378
+ """Run on agent finish."""
379
+ source = self._get_current_source()
380
+ target = "User" # Usually agents finish by returning to the user
381
+
382
+ event = FlowEvent(
383
+ source=source,
384
+ target=target,
385
+ action="Agent Finish",
386
+ message="Final Answer Ready",
387
+ trace_id=LogContext.get("trace_id", str(uuid.uuid4())),
388
+ result=str(finish.return_values),
389
+ is_return=True,
390
+ )
391
+ self.logger.info(
392
+ f"{source} -> {target}: {event.action}", extra={"flow_event": event}
393
+ )
394
+
395
+ def on_chain_error(
396
+ self,
397
+ error: BaseException,
398
+ *,
399
+ run_id: Any = None,
400
+ parent_run_id: Any = None,
401
+ **kwargs: Any,
402
+ ) -> None:
275
403
  """Run when chain errors."""
276
404
  if not self._participant_stack:
277
405
  return
@@ -291,7 +419,14 @@ class MermaidTraceCallbackHandler(BaseCallbackHandler):
291
419
  f"{target} -> {source}: {event.action}", extra={"flow_event": event}
292
420
  )
293
421
 
294
- def on_tool_error(self, error: BaseException, **kwargs: Any) -> None:
422
+ def on_tool_error(
423
+ self,
424
+ error: BaseException,
425
+ *,
426
+ run_id: Any = None,
427
+ parent_run_id: Any = None,
428
+ **kwargs: Any,
429
+ ) -> None:
295
430
  """Run when tool errors."""
296
431
  if not self._participant_stack:
297
432
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mermaid-trace
3
- Version: 0.6.0.post0
3
+ Version: 0.6.1.post0
4
4
  Summary: Visualize your Python code execution flow as Mermaid Sequence Diagrams.
5
5
  Project-URL: Documentation, https://github.com/xt765/mermaid-trace#readme
6
6
  Project-URL: Changelog, https://github.com/xt765/mermaid-trace/blob/main/docs/en/CHANGELOG.md
@@ -49,6 +49,7 @@ Requires-Dist: watchdog>=2.0.0
49
49
  Provides-Extra: all
50
50
  Requires-Dist: fastapi>=0.100.0; extra == 'all'
51
51
  Requires-Dist: langchain-core>=0.1.0; extra == 'all'
52
+ Requires-Dist: uvicorn>=0.20.0; extra == 'all'
52
53
  Provides-Extra: dev
53
54
  Requires-Dist: fastapi>=0.100.0; extra == 'dev'
54
55
  Requires-Dist: httpx; extra == 'dev'
@@ -58,8 +59,10 @@ Requires-Dist: pytest; extra == 'dev'
58
59
  Requires-Dist: pytest-asyncio; extra == 'dev'
59
60
  Requires-Dist: pytest-cov; extra == 'dev'
60
61
  Requires-Dist: ruff; extra == 'dev'
62
+ Requires-Dist: uvicorn>=0.20.0; extra == 'dev'
61
63
  Provides-Extra: fastapi
62
64
  Requires-Dist: fastapi>=0.100.0; extra == 'fastapi'
65
+ Requires-Dist: uvicorn>=0.20.0; extra == 'fastapi'
63
66
  Provides-Extra: langchain
64
67
  Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
65
68
  Description-Content-Type: text/markdown
@@ -13,9 +13,9 @@ mermaid_trace/handlers/async_handler.py,sha256=WmLcULXHasapt7-W0p_Eltjmwvlq6r6BS
13
13
  mermaid_trace/handlers/mermaid_handler.py,sha256=Czar6JYSPTu5L1fQC0I8v1UpToD6aE_r96IkPpRSByw,6142
14
14
  mermaid_trace/integrations/__init__.py,sha256=stWAHIL1zv21foaXFXZ_3SLxJ8icN0YFGWOvvHERCDI,269
15
15
  mermaid_trace/integrations/fastapi.py,sha256=6LRs4Z508l38ymfj5SP39vOV6OLfYLRkpxyL_SxvudM,9483
16
- mermaid_trace/integrations/langchain.py,sha256=n1M2-OYNMsKiMpfGj04cs_dLyn2t5T9APmgAZsqqm5Q,10598
17
- mermaid_trace-0.6.0.post0.dist-info/METADATA,sha256=kIvprKuj4jiOxpTaqumiqclh3euhw_7BkeZWg3i-YyE,10954
18
- mermaid_trace-0.6.0.post0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
19
- mermaid_trace-0.6.0.post0.dist-info/entry_points.txt,sha256=WS57KT_870v0A4B87QDjQUqJcddMQxbCQyYeczDAX34,57
20
- mermaid_trace-0.6.0.post0.dist-info/licenses/LICENSE,sha256=BrBog1Etiq9PdWy0SVQNVByIMD9ss4Edz-R0oXt49zA,1062
21
- mermaid_trace-0.6.0.post0.dist-info/RECORD,,
16
+ mermaid_trace/integrations/langchain.py,sha256=NAbfxAWybbH94ZKIgPsD6zCCc1j5gVXqUdtYlwVUVRs,14019
17
+ mermaid_trace-0.6.1.post0.dist-info/METADATA,sha256=ZW8sme2ss9f6eylmbMCxVO5Q6869XCPW8p2aSs9uyBM,11099
18
+ mermaid_trace-0.6.1.post0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
19
+ mermaid_trace-0.6.1.post0.dist-info/entry_points.txt,sha256=WS57KT_870v0A4B87QDjQUqJcddMQxbCQyYeczDAX34,57
20
+ mermaid_trace-0.6.1.post0.dist-info/licenses/LICENSE,sha256=BrBog1Etiq9PdWy0SVQNVByIMD9ss4Edz-R0oXt49zA,1062
21
+ mermaid_trace-0.6.1.post0.dist-info/RECORD,,