Ensure functions have docstrings for documentation
async def wrapped(*args: Any, **kwargs: Any) -> Any:
1"""Run managers."""23from __future__ import annotations45import asyncio6import atexit7import functools8import inspect9import logging10from abc import ABC, abstractmethod11from collections.abc import Callable, Mapping12from concurrent.futures import ThreadPoolExecutor13from contextlib import asynccontextmanager, contextmanager14from contextvars import copy_context15from typing import TYPE_CHECKING, Any, TypeVar, cast1617from typing_extensions import Self, override1819from langchain_core.callbacks.base import (20 BaseCallbackHandler,21 BaseCallbackManager,22 Callbacks,23 ChainManagerMixin,24 LLMManagerMixin,25 RetrieverManagerMixin,26 RunManagerMixin,27 ToolManagerMixin,28)29from langchain_core.callbacks.stdout import StdOutCallbackHandler30from langchain_core.globals import get_debug31from langchain_core.messages import BaseMessage, get_buffer_string32from langchain_core.utils.env import env_var_is_set33from langchain_core.utils.uuid import uuid73435if TYPE_CHECKING:36 from collections.abc import AsyncGenerator, Coroutine, Generator, Sequence37 from uuid import UUID3839 from langchain_protocol.protocol import MessagesData40 from langsmith.address import AgentAddress41 from tenacity import RetryCallState4243 from langchain_core.agents import AgentAction, AgentFinish44 from langchain_core.documents import Document45 from langchain_core.outputs import ChatGenerationChunk, GenerationChunk, LLMResult46 from langchain_core.runnables.config import RunnableConfig47 from langchain_core.tracers.schemas import Run4849logger = logging.getLogger(__name__)505152def _get_debug() -> bool:53 return get_debug()545556@contextmanager57def trace_as_chain_group(58 group_name: str,59 callback_manager: CallbackManager | None = None,60 *,61 inputs: dict[str, Any] | None = None,62 project_name: str | None = None,63 address: AgentAddress | None = None,64 example_id: str | UUID | None = None,65 run_id: UUID | None = None,66 tags: list[str] | None = None,67 metadata: dict[str, Any] | None = None,68) -> Generator[CallbackManagerForChainGroup, None, None]:69 """Get a callback manager for a chain group in a context manager.7071 Useful for grouping different calls together as a single run even if they aren't72 composed in a single chain.7374 Args:75 group_name: The name of the chain group.76 callback_manager: The callback manager to use.77 inputs: The inputs to the chain group.78 project_name: The name of the project.79 address: The agent address to send traces to instead of a project.8081 !!! warning "Beta"82 Agent addressing must be enabled for the LangSmith workspace.83 example_id: The ID of the example.84 run_id: The ID of the run.85 tags: The inheritable tags to apply to all runs.86 metadata: The metadata to apply to all runs.8788 !!! note8990 Must have `LANGCHAIN_TRACING_V2` env var set to true to see the trace in91 LangSmith.9293 Yields:94 The callback manager for the chain group.9596 Example:97 ```python98 llm_input = "Foo"99 with trace_as_chain_group("group_name", inputs={"input": llm_input}) as manager:100 # Use the callback manager for the chain group101 res = llm.invoke(llm_input, {"callbacks": manager})102 manager.on_chain_end({"output": res})103 ```104 """105 from langchain_core.tracers.context import ( # noqa: PLC0415 -- deferred to avoid importing langsmith at module level106 _get_trace_callbacks,107 )108109 cb = _get_trace_callbacks(110 project_name, example_id, callback_manager=callback_manager, address=address111 )112 cm = CallbackManager.configure(113 inheritable_callbacks=cb,114 inheritable_tags=tags,115 inheritable_metadata=metadata,116 )117118 run_manager = cm.on_chain_start({"name": group_name}, inputs or {}, run_id=run_id)119 child_cm = run_manager.get_child()120 group_cm = CallbackManagerForChainGroup(121 child_cm.handlers,122 child_cm.inheritable_handlers,123 child_cm.parent_run_id,124 parent_run_manager=run_manager,125 tags=child_cm.tags,126 inheritable_tags=child_cm.inheritable_tags,127 metadata=child_cm.metadata,128 inheritable_metadata=child_cm.inheritable_metadata,129 )130 try:131 yield group_cm132 except BaseException as e:133 if not group_cm.ended:134 run_manager.on_chain_error(e)135 raise136 else:137 if not group_cm.ended:138 run_manager.on_chain_end({})139140141@asynccontextmanager142async def atrace_as_chain_group(143 group_name: str,144 callback_manager: AsyncCallbackManager | None = None,145 *,146 inputs: dict[str, Any] | None = None,147 project_name: str | None = None,148 address: AgentAddress | None = None,149 example_id: str | UUID | None = None,150 run_id: UUID | None = None,151 tags: list[str] | None = None,152 metadata: dict[str, Any] | None = None,153) -> AsyncGenerator[AsyncCallbackManagerForChainGroup, None]:154 """Get an async callback manager for a chain group in a context manager.155156 Useful for grouping different async calls together as a single run even if they157 aren't composed in a single chain.158159 Args:160 group_name: The name of the chain group.161 callback_manager: The async callback manager to use, which manages tracing and162 other callback behavior.163 inputs: The inputs to the chain group.164 project_name: The name of the project.165 address: The agent address to send traces to instead of a project.166167 !!! warning "Beta"168 Agent addressing must be enabled for the LangSmith workspace.169 example_id: The ID of the example.170 run_id: The ID of the run.171 tags: The inheritable tags to apply to all runs.172 metadata: The metadata to apply to all runs.173174 Yields:175 The async callback manager for the chain group.176177 !!! note178179 Must have `LANGCHAIN_TRACING_V2` env var set to true to see the trace in180 LangSmith.181182 Example:183 ```python184 llm_input = "Foo"185 async with atrace_as_chain_group(186 "group_name", inputs={"input": llm_input}187 ) as manager:188 # Use the async callback manager for the chain group189 res = await llm.ainvoke(llm_input, {"callbacks": manager})190 await manager.on_chain_end({"output": res})191 ```192 """193 from langchain_core.tracers.context import ( # noqa: PLC0415 -- deferred to avoid importing langsmith at module level194 _get_trace_callbacks,195 )196197 cb = _get_trace_callbacks(198 project_name, example_id, callback_manager=callback_manager, address=address199 )200 cm = AsyncCallbackManager.configure(201 inheritable_callbacks=cb, inheritable_tags=tags, inheritable_metadata=metadata202 )203204 run_manager = await cm.on_chain_start(205 {"name": group_name}, inputs or {}, run_id=run_id206 )207 child_cm = run_manager.get_child()208 group_cm = AsyncCallbackManagerForChainGroup(209 child_cm.handlers,210 child_cm.inheritable_handlers,211 child_cm.parent_run_id,212 parent_run_manager=run_manager,213 tags=child_cm.tags,214 inheritable_tags=child_cm.inheritable_tags,215 metadata=child_cm.metadata,216 inheritable_metadata=child_cm.inheritable_metadata,217 )218 try:219 yield group_cm220 except BaseException as e:221 if not group_cm.ended:222 await run_manager.on_chain_error(e)223 raise224 else:225 if not group_cm.ended:226 await run_manager.on_chain_end({})227228229Func = TypeVar("Func", bound=Callable[..., Any])230231232def shielded(func: Func) -> Func:233 """Makes so an awaitable method is always shielded from cancellation.234235 Args:236 func: The function to shield.237238 Returns:239 The shielded function240241 """242243 @functools.wraps(func)244 async def wrapped(*args: Any, **kwargs: Any) -> Any:245 # Capture the current context to preserve context variables246 ctx = copy_context()247248 # Create the coroutine249 coro = func(*args, **kwargs)250251 # For Python 3.11+, create task with explicit context252 # For older versions, fallback to original behavior253 try:254 # Create a task with the captured context to preserve context variables255 task = asyncio.create_task(coro, context=ctx) # type: ignore[call-arg, unused-ignore]256 # `call-arg` used to not fail 3.9 or 3.10 tests257 return await asyncio.shield(task)258 except TypeError:259 # Python < 3.11 fallback - create task normally then shield260 # This won't preserve context perfectly but is better than nothing261 task = asyncio.create_task(coro)262 return await asyncio.shield(task)263264 return cast("Func", wrapped)265266267async def _achat_model_start_fallback(268 coro: Coroutine[Any, Any, Any],269 handler: BaseCallbackHandler,270 *args: Any,271 **kwargs: Any,272) -> None:273 """Wrap an async `on_chat_model_start` coroutine with fallback.274275 Catches `NotImplementedError` and triggers the `on_llm_start` fallback.276 This covers async handlers invoked from a **sync** `handle_event` call,277 where the coroutine is collected into `coros` and executed later by278 `_run_coros`. Without this wrapper the `NotImplementedError` would be279 caught generically by `_run_coros` and the trace would be lost.280 """281 try:282 await coro283 except NotImplementedError:284 message_strings = [get_buffer_string(m) for m in args[1]]285 await _ahandle_event_for_handler(286 handler,287 "on_llm_start",288 "ignore_llm",289 args[0],290 message_strings,291 *args[2:],292 **kwargs,293 )294295296def handle_event(297 handlers: list[BaseCallbackHandler],298 event_name: str,299 ignore_condition_name: str | None,300 *args: Any,301 **kwargs: Any,302) -> None:303 """Generic event handler for `CallbackManager`.304305 Args:306 handlers: The list of handlers that will handle the event.307 event_name: The name of the event (e.g., `'on_llm_start'`).308 ignore_condition_name: Name of the attribute defined on handler that if `True`309 will cause the handler to be skipped for the given event.310 *args: The arguments to pass to the event handler.311 **kwargs: The keyword arguments to pass to the event handler312313 """314 coros: list[Coroutine[Any, Any, Any]] = []315316 try:317 message_strings: list[str] | None = None318 for handler in handlers:319 try:320 if ignore_condition_name is None or not getattr(321 handler, ignore_condition_name322 ):323 event = getattr(handler, event_name)(*args, **kwargs)324 if asyncio.iscoroutine(event):325 if event_name == "on_chat_model_start":326 event = _achat_model_start_fallback(327 event, handler, *args, **kwargs328 )329 coros.append(event)330 except NotImplementedError as e:331 if event_name == "on_chat_model_start":332 if message_strings is None:333 message_strings = [get_buffer_string(m) for m in args[1]]334 handle_event(335 [handler],336 "on_llm_start",337 "ignore_llm",338 args[0],339 message_strings,340 *args[2:],341 **kwargs,342 )343 else:344 handler_name = handler.__class__.__name__345 logger.warning(346 "NotImplementedError in %s.%s callback: %s",347 handler_name,348 event_name,349 repr(e),350 )351 except Exception as e:352 logger.warning(353 "Error in %s.%s callback: %s",354 handler.__class__.__name__,355 event_name,356 repr(e),357 )358 if handler.raise_error:359 raise360 finally:361 if coros:362 try:363 # Raises RuntimeError if there is no current event loop.364 asyncio.get_running_loop()365 loop_running = True366 except RuntimeError:367 loop_running = False368369 if loop_running:370 # If we try to submit this coroutine to the running loop371 # we end up in a deadlock, as we'd have gotten here from a372 # running coroutine, which we cannot interrupt to run this one.373 # The solution is to run the synchronous function on the globally shared374 # thread pool executor to avoid blocking the main event loop.375 _executor().submit(copy_context().run, _run_coros, coros).result()376 else:377 # If there's no running loop, we can run the coroutines directly.378 _run_coros(coros)379380381def _run_coros(coros: list[Coroutine[Any, Any, Any]]) -> None:382 # Note: exceptions raised by these coroutines are always logged and swallowed383 # here, regardless of the handler's `raise_error` setting. Async-handler errors384 # driven through sync `handle_event` therefore never propagate, unlike errors385 # from sync handlers (which honor `raise_error`). This is a pre-existing386 # asymmetry between the sync and async callback paths.387 if hasattr(asyncio, "Runner"):388 # Python 3.11+389 # Run the coroutines in a new event loop, taking care to390 # - install signal handlers391 # - run pending tasks scheduled by `coros`392 # - close asyncgens and executors393 # - close the loop394 with asyncio.Runner() as runner:395 # Run the coroutine, get the result396 for coro in coros:397 try:398 runner.run(coro)399 except Exception as e:400 logger.warning("Error in callback coroutine: %s", repr(e))401402 # Run pending tasks scheduled by coros until they are all done403 while pending := asyncio.all_tasks(runner.get_loop()):404 runner.run(asyncio.wait(pending))405 else:406 # Before Python 3.11 we need to run each coroutine in a new event loop407 # as the Runner api is not available.408 for coro in coros:409 try:410 asyncio.run(coro)411 except Exception as e:412 logger.warning("Error in callback coroutine: %s", repr(e))413414415async def _ahandle_event_for_handler(416 handler: BaseCallbackHandler,417 event_name: str,418 ignore_condition_name: str | None,419 *args: Any,420 **kwargs: Any,421) -> None:422 try:423 if ignore_condition_name is None or not getattr(handler, ignore_condition_name):424 event = getattr(handler, event_name)425 if inspect.iscoroutinefunction(event):426 await event(*args, **kwargs)427 elif handler.run_inline:428 event(*args, **kwargs)429 else:430 await asyncio.get_running_loop().run_in_executor(431 None,432 functools.partial(copy_context().run, event, *args, **kwargs),433 )434 except NotImplementedError as e:435 if event_name == "on_chat_model_start":436 message_strings = [get_buffer_string(m) for m in args[1]]437 await _ahandle_event_for_handler(438 handler,439 "on_llm_start",440 "ignore_llm",441 args[0],442 message_strings,443 *args[2:],444 **kwargs,445 )446 else:447 logger.warning(448 "NotImplementedError in %s.%s callback: %s",449 handler.__class__.__name__,450 event_name,451 repr(e),452 )453 except Exception as e:454 logger.warning(455 "Error in %s.%s callback: %s",456 handler.__class__.__name__,457 event_name,458 repr(e),459 )460 if handler.raise_error:461 raise462463464async def ahandle_event(465 handlers: list[BaseCallbackHandler],466 event_name: str,467 ignore_condition_name: str | None,468 *args: Any,469 **kwargs: Any,470) -> None:471 """Async generic event handler for `AsyncCallbackManager`.472473 Args:474 handlers: The list of handlers that will handle the event.475 event_name: The name of the event (e.g., `'on_llm_start'`).476 ignore_condition_name: Name of the attribute defined on handler that if `True`477 will cause the handler to be skipped for the given event.478 *args: The arguments to pass to the event handler.479 **kwargs: The keyword arguments to pass to the event handler.480481 """482 for handler in [h for h in handlers if h.run_inline]:483 await _ahandle_event_for_handler(484 handler, event_name, ignore_condition_name, *args, **kwargs485 )486 await asyncio.gather(487 *(488 _ahandle_event_for_handler(489 handler,490 event_name,491 ignore_condition_name,492 *args,493 **kwargs,494 )495 for handler in handlers496 if not handler.run_inline497 )498 )499500501class BaseRunManager(RunManagerMixin):502 """Base class for run manager (a bound callback manager)."""503504 def __init__(505 self,506 *,507 run_id: UUID,508 handlers: list[BaseCallbackHandler],509 inheritable_handlers: list[BaseCallbackHandler],510 parent_run_id: UUID | None = None,511 tags: list[str] | None = None,512 inheritable_tags: list[str] | None = None,513 metadata: dict[str, Any] | None = None,514 inheritable_metadata: dict[str, Any] | None = None,515 ) -> None:516 """Initialize the run manager.517518 Args:519 run_id: The ID of the run.520 handlers: The list of handlers.521 inheritable_handlers: The list of inheritable handlers.522 parent_run_id: The ID of the parent run.523 tags: The list of tags.524 inheritable_tags: The list of inheritable tags.525 metadata: The metadata.526 inheritable_metadata: The inheritable metadata.527528 """529 self.run_id = run_id530 self.handlers = handlers531 self.inheritable_handlers = inheritable_handlers532 self.parent_run_id = parent_run_id533 self.tags = tags or []534 self.inheritable_tags = inheritable_tags or []535 self.metadata = metadata or {}536 self.inheritable_metadata = inheritable_metadata or {}537538 @classmethod539 def get_noop_manager(cls) -> Self:540 """Return a manager that doesn't perform any operations.541542 Returns:543 The noop manager.544545 """546 return cls(547 run_id=uuid7(),548 handlers=[],549 inheritable_handlers=[],550 tags=[],551 inheritable_tags=[],552 metadata={},553 inheritable_metadata={},554 )555556557class RunManager(BaseRunManager):558 """Synchronous run manager."""559560 def on_text(561 self,562 text: str,563 **kwargs: Any,564 ) -> None:565 """Run when a text is received.566567 Args:568 text: The received text.569 **kwargs: Additional keyword arguments.570 """571 if not self.handlers:572 return573 handle_event(574 self.handlers,575 "on_text",576 None,577 text,578 run_id=self.run_id,579 parent_run_id=self.parent_run_id,580 tags=self.tags,581 **kwargs,582 )583584 def on_retry(585 self,586 retry_state: RetryCallState,587 **kwargs: Any,588 ) -> None:589 """Run when a retry is received.590591 Args:592 retry_state: The retry state.593 **kwargs: Additional keyword arguments.594595 """596 if not self.handlers:597 return598 handle_event(599 self.handlers,600 "on_retry",601 "ignore_retry",602 retry_state,603 run_id=self.run_id,604 parent_run_id=self.parent_run_id,605 tags=self.tags,606 **kwargs,607 )608609610class ParentRunManager(RunManager):611 """Synchronous parent run manager."""612613 def get_child(self, tag: str | None = None) -> CallbackManager:614 """Get a child callback manager.615616 Args:617 tag: The tag for the child callback manager.618619 Returns:620 The child callback manager.621622 """623 manager = CallbackManager(handlers=[], parent_run_id=self.run_id)624 manager.set_handlers(self.inheritable_handlers)625 manager.add_tags(self.inheritable_tags)626 manager.add_metadata(self.inheritable_metadata)627 if tag is not None:628 manager.add_tags([tag], inherit=False)629 return manager630631632class AsyncRunManager(BaseRunManager, ABC):633 """Async run manager."""634635 @abstractmethod636 def get_sync(self) -> RunManager:637 """Get the equivalent sync `RunManager`.638639 Returns:640 The sync `RunManager`.641642 """643644 async def on_text(645 self,646 text: str,647 **kwargs: Any,648 ) -> None:649 """Run when a text is received.650651 Args:652 text: The received text.653 **kwargs: Additional keyword arguments.654 """655 if not self.handlers:656 return657 await ahandle_event(658 self.handlers,659 "on_text",660 None,661 text,662 run_id=self.run_id,663 parent_run_id=self.parent_run_id,664 tags=self.tags,665 **kwargs,666 )667668 async def on_retry(669 self,670 retry_state: RetryCallState,671 **kwargs: Any,672 ) -> None:673 """Async run when a retry is received.674675 Args:676 retry_state: The retry state.677 **kwargs: Additional keyword arguments.678679 """680 if not self.handlers:681 return682 await ahandle_event(683 self.handlers,684 "on_retry",685 "ignore_retry",686 retry_state,687 run_id=self.run_id,688 parent_run_id=self.parent_run_id,689 tags=self.tags,690 **kwargs,691 )692693694class AsyncParentRunManager(AsyncRunManager):695 """Async parent run manager."""696697 def get_child(self, tag: str | None = None) -> AsyncCallbackManager:698 """Get a child callback manager.699700 Args:701 tag: The tag for the child callback manager.702703 Returns:704 The child callback manager.705706 """707 manager = AsyncCallbackManager(handlers=[], parent_run_id=self.run_id)708 manager.set_handlers(self.inheritable_handlers)709 manager.add_tags(self.inheritable_tags)710 manager.add_metadata(self.inheritable_metadata)711 if tag is not None:712 manager.add_tags([tag], inherit=False)713 return manager714715716class CallbackManagerForLLMRun(RunManager, LLMManagerMixin):717 """Callback manager for LLM run."""718719 def on_llm_new_token(720 self,721 token: str | list[str | dict[str, Any]],722 *,723 chunk: GenerationChunk | ChatGenerationChunk | None = None,724 **kwargs: Any,725 ) -> None:726 """Run when LLM generates a new token.727728 Args:729 token: The new token, or a list of content blocks.730 chunk: The chunk.731 **kwargs: Additional keyword arguments.732733 """734 if not self.handlers:735 return736 handle_event(737 self.handlers,738 "on_llm_new_token",739 "ignore_llm",740 token=token,741 run_id=self.run_id,742 parent_run_id=self.parent_run_id,743 tags=self.tags,744 chunk=chunk,745 **kwargs,746 )747748 def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:749 """Run when LLM ends running.750751 Args:752 response: The LLM result.753 **kwargs: Additional keyword arguments.754755 """756 if not self.handlers:757 return758 handle_event(759 self.handlers,760 "on_llm_end",761 "ignore_llm",762 response,763 run_id=self.run_id,764 parent_run_id=self.parent_run_id,765 tags=self.tags,766 **kwargs,767 )768769 def on_llm_error(770 self,771 error: BaseException,772 **kwargs: Any,773 ) -> None:774 """Run when LLM errors.775776 Args:777 error: The error.778 **kwargs: Additional keyword arguments.779780 - response (LLMResult): The response which was generated before781 the error occurred.782 """783 if not self.handlers:784 return785 handle_event(786 self.handlers,787 "on_llm_error",788 "ignore_llm",789 error,790 run_id=self.run_id,791 parent_run_id=self.parent_run_id,792 tags=self.tags,793 **kwargs,794 )795796 def on_stream_event(self, event: MessagesData, **kwargs: Any) -> None:797 """Run on each protocol event from `stream_events(version="v3")`.798799 Args:800 event: The protocol event.801 **kwargs: Additional keyword arguments.802 """803 if not self.handlers:804 return805 handle_event(806 self.handlers,807 "on_stream_event",808 "ignore_llm",809 event,810 run_id=self.run_id,811 parent_run_id=self.parent_run_id,812 tags=self.tags,813 **kwargs,814 )815816817class AsyncCallbackManagerForLLMRun(AsyncRunManager, LLMManagerMixin):818 """Async callback manager for LLM run."""819820 def get_sync(self) -> CallbackManagerForLLMRun:821 """Get the equivalent sync `RunManager`.822823 Returns:824 The sync `RunManager`.825826 """827 return CallbackManagerForLLMRun(828 run_id=self.run_id,829 handlers=self.handlers,830 inheritable_handlers=self.inheritable_handlers,831 parent_run_id=self.parent_run_id,832 tags=self.tags,833 inheritable_tags=self.inheritable_tags,834 metadata=self.metadata,835 inheritable_metadata=self.inheritable_metadata,836 )837838 async def on_llm_new_token(839 self,840 token: str | list[str | dict[str, Any]],841 *,842 chunk: GenerationChunk | ChatGenerationChunk | None = None,843 **kwargs: Any,844 ) -> None:845 """Run when LLM generates a new token.846847 Args:848 token: The new token, or a list of content blocks.849 chunk: The chunk.850 **kwargs: Additional keyword arguments.851852 """853 if not self.handlers:854 return855 await ahandle_event(856 self.handlers,857 "on_llm_new_token",858 "ignore_llm",859 token,860 chunk=chunk,861 run_id=self.run_id,862 parent_run_id=self.parent_run_id,863 tags=self.tags,864 **kwargs,865 )866867 @shielded868 async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:869 """Run when LLM ends running.870871 Args:872 response: The LLM result.873 **kwargs: Additional keyword arguments.874875 """876 if not self.handlers:877 return878 await ahandle_event(879 self.handlers,880 "on_llm_end",881 "ignore_llm",882 response,883 run_id=self.run_id,884 parent_run_id=self.parent_run_id,885 tags=self.tags,886 **kwargs,887 )888889 @shielded890 async def on_llm_error(891 self,892 error: BaseException,893 **kwargs: Any,894 ) -> None:895 """Run when LLM errors.896897 Args:898 error: The error.899 **kwargs: Additional keyword arguments.900901 - response (LLMResult): The response which was generated before902 the error occurred.903904 """905 if not self.handlers:906 return907 await ahandle_event(908 self.handlers,909 "on_llm_error",910 "ignore_llm",911 error,912 run_id=self.run_id,913 parent_run_id=self.parent_run_id,914 tags=self.tags,915 **kwargs,916 )917918 async def on_stream_event(self, event: MessagesData, **kwargs: Any) -> None:919 """Run on each protocol event from `astream_events(version="v3")`.920921 Args:922 event: The protocol event.923 **kwargs: Additional keyword arguments.924 """925 if not self.handlers:926 return927 await ahandle_event(928 self.handlers,929 "on_stream_event",930 "ignore_llm",931 event,932 run_id=self.run_id,933 parent_run_id=self.parent_run_id,934 tags=self.tags,935 **kwargs,936 )937938939class CallbackManagerForChainRun(ParentRunManager, ChainManagerMixin):940 """Callback manager for chain run."""941942 def on_chain_end(self, outputs: dict[str, Any] | Any, **kwargs: Any) -> None:943 """Run when chain ends running.944945 Args:946 outputs: The outputs of the chain.947 **kwargs: Additional keyword arguments.948949 """950 if not self.handlers:951 return952 handle_event(953 self.handlers,954 "on_chain_end",955 "ignore_chain",956 outputs,957 run_id=self.run_id,958 parent_run_id=self.parent_run_id,959 tags=self.tags,960 **kwargs,961 )962963 def on_chain_error(964 self,965 error: BaseException,966 **kwargs: Any,967 ) -> None:968 """Run when chain errors.969970 Args:971 error: The error.972 **kwargs: Additional keyword arguments.973974 """975 if not self.handlers:976 return977 handle_event(978 self.handlers,979 "on_chain_error",980 "ignore_chain",981 error,982 run_id=self.run_id,983 parent_run_id=self.parent_run_id,984 tags=self.tags,985 **kwargs,986 )987988 def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None:989 """Run when agent action is received.990991 Args:992 action: The agent action.993 **kwargs: Additional keyword arguments.994 """995 if not self.handlers:996 return997 handle_event(998 self.handlers,999 "on_agent_action",1000 "ignore_agent",1001 action,1002 run_id=self.run_id,1003 parent_run_id=self.parent_run_id,1004 tags=self.tags,1005 **kwargs,1006 )10071008 def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None:1009 """Run when agent finish is received.10101011 Args:1012 finish: The agent finish.1013 **kwargs: Additional keyword arguments.1014 """1015 if not self.handlers:1016 return1017 handle_event(1018 self.handlers,1019 "on_agent_finish",1020 "ignore_agent",1021 finish,1022 run_id=self.run_id,1023 parent_run_id=self.parent_run_id,1024 tags=self.tags,1025 **kwargs,1026 )102710281029class AsyncCallbackManagerForChainRun(AsyncParentRunManager, ChainManagerMixin):1030 """Async callback manager for chain run."""10311032 def get_sync(self) -> CallbackManagerForChainRun:1033 """Get the equivalent sync `RunManager`.10341035 Returns:1036 The sync `RunManager`.1037 """1038 return CallbackManagerForChainRun(1039 run_id=self.run_id,1040 handlers=self.handlers,1041 inheritable_handlers=self.inheritable_handlers,1042 parent_run_id=self.parent_run_id,1043 tags=self.tags,1044 inheritable_tags=self.inheritable_tags,1045 metadata=self.metadata,1046 inheritable_metadata=self.inheritable_metadata,1047 )10481049 @shielded1050 async def on_chain_end(self, outputs: dict[str, Any] | Any, **kwargs: Any) -> None:1051 """Run when a chain ends running.10521053 Args:1054 outputs: The outputs of the chain.1055 **kwargs: Additional keyword arguments.10561057 """1058 if not self.handlers:1059 return1060 await ahandle_event(1061 self.handlers,1062 "on_chain_end",1063 "ignore_chain",1064 outputs,1065 run_id=self.run_id,1066 parent_run_id=self.parent_run_id,1067 tags=self.tags,1068 **kwargs,1069 )10701071 @shielded1072 async def on_chain_error(1073 self,1074 error: BaseException,1075 **kwargs: Any,1076 ) -> None:1077 """Run when chain errors.10781079 Args:1080 error: The error.1081 **kwargs: Additional keyword arguments.10821083 """1084 if not self.handlers:1085 return1086 await ahandle_event(1087 self.handlers,1088 "on_chain_error",1089 "ignore_chain",1090 error,1091 run_id=self.run_id,1092 parent_run_id=self.parent_run_id,1093 tags=self.tags,1094 **kwargs,1095 )10961097 async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None:1098 """Run when agent action is received.10991100 Args:1101 action: The agent action.1102 **kwargs: Additional keyword arguments.1103 """1104 if not self.handlers:1105 return1106 await ahandle_event(1107 self.handlers,1108 "on_agent_action",1109 "ignore_agent",1110 action,1111 run_id=self.run_id,1112 parent_run_id=self.parent_run_id,1113 tags=self.tags,1114 **kwargs,1115 )11161117 async def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None:1118 """Run when agent finish is received.11191120 Args:1121 finish: The agent finish.1122 **kwargs: Additional keyword arguments.1123 """1124 if not self.handlers:1125 return1126 await ahandle_event(1127 self.handlers,1128 "on_agent_finish",1129 "ignore_agent",1130 finish,1131 run_id=self.run_id,1132 parent_run_id=self.parent_run_id,1133 tags=self.tags,1134 **kwargs,1135 )113611371138class CallbackManagerForToolRun(ParentRunManager, ToolManagerMixin):1139 """Callback manager for tool run."""11401141 def on_tool_end(1142 self,1143 output: Any,1144 **kwargs: Any,1145 ) -> None:1146 """Run when the tool ends running.11471148 Args:1149 output: The output of the tool.1150 **kwargs: The keyword arguments to pass to the event handler11511152 """1153 if not self.handlers:1154 return1155 handle_event(1156 self.handlers,1157 "on_tool_end",1158 "ignore_agent",1159 output,1160 run_id=self.run_id,1161 parent_run_id=self.parent_run_id,1162 tags=self.tags,1163 **kwargs,1164 )11651166 def on_tool_error(1167 self,1168 error: BaseException,1169 **kwargs: Any,1170 ) -> None:1171 """Run when tool errors.11721173 Args:1174 error: The error.1175 **kwargs: Additional keyword arguments.11761177 """1178 if not self.handlers:1179 return1180 handle_event(1181 self.handlers,1182 "on_tool_error",1183 "ignore_agent",1184 error,1185 run_id=self.run_id,1186 parent_run_id=self.parent_run_id,1187 tags=self.tags,1188 **kwargs,1189 )119011911192class AsyncCallbackManagerForToolRun(AsyncParentRunManager, ToolManagerMixin):1193 """Async callback manager for tool run."""11941195 def get_sync(self) -> CallbackManagerForToolRun:1196 """Get the equivalent sync `RunManager`.11971198 Returns:1199 The sync `RunManager`.1200 """1201 return CallbackManagerForToolRun(1202 run_id=self.run_id,1203 handlers=self.handlers,1204 inheritable_handlers=self.inheritable_handlers,1205 parent_run_id=self.parent_run_id,1206 tags=self.tags,1207 inheritable_tags=self.inheritable_tags,1208 metadata=self.metadata,1209 inheritable_metadata=self.inheritable_metadata,1210 )12111212 async def on_tool_end(self, output: Any, **kwargs: Any) -> None:1213 """Async run when the tool ends running.12141215 Args:1216 output: The output of the tool.1217 **kwargs: Additional keyword arguments.12181219 """1220 if not self.handlers:1221 return1222 await ahandle_event(1223 self.handlers,1224 "on_tool_end",1225 "ignore_agent",1226 output,1227 run_id=self.run_id,1228 parent_run_id=self.parent_run_id,1229 tags=self.tags,1230 **kwargs,1231 )12321233 async def on_tool_error(1234 self,1235 error: BaseException,1236 **kwargs: Any,1237 ) -> None:1238 """Run when tool errors.12391240 Args:1241 error: The error.1242 **kwargs: Additional keyword arguments.12431244 """1245 if not self.handlers:1246 return1247 await ahandle_event(1248 self.handlers,1249 "on_tool_error",1250 "ignore_agent",1251 error,1252 run_id=self.run_id,1253 parent_run_id=self.parent_run_id,1254 tags=self.tags,1255 **kwargs,1256 )125712581259class CallbackManagerForRetrieverRun(ParentRunManager, RetrieverManagerMixin):1260 """Callback manager for retriever run."""12611262 def on_retriever_end(1263 self,1264 documents: Sequence[Document],1265 **kwargs: Any,1266 ) -> None:1267 """Run when retriever ends running.12681269 Args:1270 documents: The retrieved documents.1271 **kwargs: Additional keyword arguments.12721273 """1274 if not self.handlers:1275 return1276 handle_event(1277 self.handlers,1278 "on_retriever_end",1279 "ignore_retriever",1280 documents,1281 run_id=self.run_id,1282 parent_run_id=self.parent_run_id,1283 tags=self.tags,1284 **kwargs,1285 )12861287 def on_retriever_error(1288 self,1289 error: BaseException,1290 **kwargs: Any,1291 ) -> None:1292 """Run when retriever errors.12931294 Args:1295 error: The error.1296 **kwargs: Additional keyword arguments.12971298 """1299 if not self.handlers:1300 return1301 handle_event(1302 self.handlers,1303 "on_retriever_error",1304 "ignore_retriever",1305 error,1306 run_id=self.run_id,1307 parent_run_id=self.parent_run_id,1308 tags=self.tags,1309 **kwargs,1310 )131113121313class AsyncCallbackManagerForRetrieverRun(1314 AsyncParentRunManager,1315 RetrieverManagerMixin,1316):1317 """Async callback manager for retriever run."""13181319 def get_sync(self) -> CallbackManagerForRetrieverRun:1320 """Get the equivalent sync `RunManager`.13211322 Returns:1323 The sync `RunManager`.13241325 """1326 return CallbackManagerForRetrieverRun(1327 run_id=self.run_id,1328 handlers=self.handlers,1329 inheritable_handlers=self.inheritable_handlers,1330 parent_run_id=self.parent_run_id,1331 tags=self.tags,1332 inheritable_tags=self.inheritable_tags,1333 metadata=self.metadata,1334 inheritable_metadata=self.inheritable_metadata,1335 )13361337 @shielded1338 async def on_retriever_end(1339 self, documents: Sequence[Document], **kwargs: Any1340 ) -> None:1341 """Run when the retriever ends running.13421343 Args:1344 documents: The retrieved documents.1345 **kwargs: Additional keyword arguments.13461347 """1348 if not self.handlers:1349 return1350 await ahandle_event(1351 self.handlers,1352 "on_retriever_end",1353 "ignore_retriever",1354 documents,1355 run_id=self.run_id,1356 parent_run_id=self.parent_run_id,1357 tags=self.tags,1358 **kwargs,1359 )13601361 @shielded1362 async def on_retriever_error(1363 self,1364 error: BaseException,1365 **kwargs: Any,1366 ) -> None:1367 """Run when retriever errors.13681369 Args:1370 error: The error.1371 **kwargs: Additional keyword arguments.13721373 """1374 if not self.handlers:1375 return1376 await ahandle_event(1377 self.handlers,1378 "on_retriever_error",1379 "ignore_retriever",1380 error,1381 run_id=self.run_id,1382 parent_run_id=self.parent_run_id,1383 tags=self.tags,1384 **kwargs,1385 )138613871388class CallbackManager(BaseCallbackManager):1389 """Callback manager for LangChain."""13901391 def on_llm_start(1392 self,1393 serialized: dict[str, Any],1394 prompts: list[str],1395 run_id: UUID | None = None,1396 **kwargs: Any,1397 ) -> list[CallbackManagerForLLMRun]:1398 """Run when LLM starts running.13991400 Args:1401 serialized: The serialized LLM.1402 prompts: The list of prompts.1403 run_id: The ID of the run.1404 **kwargs: Additional keyword arguments.14051406 Returns:1407 A callback manager for each prompt as an LLM run.14081409 """1410 managers = []1411 for i, prompt in enumerate(prompts):1412 # Can't have duplicate runs with the same run ID (if provided)1413 run_id_ = run_id if i == 0 and run_id is not None else uuid7()1414 handle_event(1415 self.handlers,1416 "on_llm_start",1417 "ignore_llm",1418 serialized,1419 [prompt],1420 run_id=run_id_,1421 parent_run_id=self.parent_run_id,1422 tags=self.tags,1423 metadata=self.metadata,1424 **kwargs,1425 )14261427 managers.append(1428 CallbackManagerForLLMRun(1429 run_id=run_id_,1430 handlers=self.handlers,1431 inheritable_handlers=self.inheritable_handlers,1432 parent_run_id=self.parent_run_id,1433 tags=self.tags,1434 inheritable_tags=self.inheritable_tags,1435 metadata=self.metadata,1436 inheritable_metadata=self.inheritable_metadata,1437 )1438 )14391440 return managers14411442 def on_chat_model_start(1443 self,1444 serialized: dict[str, Any],1445 messages: list[list[BaseMessage]],1446 run_id: UUID | None = None,1447 **kwargs: Any,1448 ) -> list[CallbackManagerForLLMRun]:1449 """Run when chat model starts running.14501451 Args:1452 serialized: The serialized LLM.1453 messages: The list of messages.1454 run_id: The ID of the run.1455 **kwargs: Additional keyword arguments.14561457 Returns:1458 A callback manager for each list of messages as an LLM run.14591460 """1461 managers = []1462 for message_list in messages:1463 if run_id is not None:1464 run_id_ = run_id1465 run_id = None1466 else:1467 run_id_ = uuid7()1468 handle_event(1469 self.handlers,1470 "on_chat_model_start",1471 "ignore_chat_model",1472 serialized,1473 [message_list],1474 run_id=run_id_,1475 parent_run_id=self.parent_run_id,1476 tags=self.tags,1477 metadata=self.metadata,1478 **kwargs,1479 )14801481 managers.append(1482 CallbackManagerForLLMRun(1483 run_id=run_id_,1484 handlers=self.handlers,1485 inheritable_handlers=self.inheritable_handlers,1486 parent_run_id=self.parent_run_id,1487 tags=self.tags,1488 inheritable_tags=self.inheritable_tags,1489 metadata=self.metadata,1490 inheritable_metadata=self.inheritable_metadata,1491 )1492 )14931494 return managers14951496 def on_chain_start(1497 self,1498 serialized: dict[str, Any] | None,1499 inputs: dict[str, Any] | Any,1500 run_id: UUID | None = None,1501 **kwargs: Any,1502 ) -> CallbackManagerForChainRun:1503 """Run when chain starts running.15041505 Args:1506 serialized: The serialized chain.1507 inputs: The inputs to the chain.1508 run_id: The ID of the run.1509 **kwargs: Additional keyword arguments.15101511 Returns:1512 The callback manager for the chain run.15131514 """1515 if run_id is None:1516 run_id = uuid7()1517 handle_event(1518 self.handlers,1519 "on_chain_start",1520 "ignore_chain",1521 serialized,1522 inputs,1523 run_id=run_id,1524 parent_run_id=self.parent_run_id,1525 tags=self.tags,1526 metadata=self.metadata,1527 **kwargs,1528 )15291530 return CallbackManagerForChainRun(1531 run_id=run_id,1532 handlers=self.handlers,1533 inheritable_handlers=self.inheritable_handlers,1534 parent_run_id=self.parent_run_id,1535 tags=self.tags,1536 inheritable_tags=self.inheritable_tags,1537 metadata=self.metadata,1538 inheritable_metadata=self.inheritable_metadata,1539 )15401541 @override1542 def on_tool_start(1543 self,1544 serialized: dict[str, Any] | None,1545 input_str: str,1546 run_id: UUID | None = None,1547 parent_run_id: UUID | None = None,1548 inputs: dict[str, Any] | None = None,1549 **kwargs: Any,1550 ) -> CallbackManagerForToolRun:1551 """Run when tool starts running.15521553 Args:1554 serialized: Serialized representation of the tool.1555 input_str: The input to the tool as a string.15561557 Non-string inputs are cast to strings.1558 run_id: ID for the run.1559 parent_run_id: The ID of the parent run.1560 inputs: The original input to the tool if provided.15611562 Recommended for usage instead of input_str when the original input is1563 needed.15641565 If provided, the inputs are expected to be formatted as a dict. The keys1566 will correspond to the named-arguments in the tool.1567 **kwargs: The keyword arguments to pass to the event handler15681569 Returns:1570 The callback manager for the tool run.15711572 """1573 if run_id is None:1574 run_id = uuid7()15751576 handle_event(1577 self.handlers,1578 "on_tool_start",1579 "ignore_agent",1580 serialized,1581 input_str,1582 run_id=run_id,1583 parent_run_id=self.parent_run_id,1584 tags=self.tags,1585 metadata=self.metadata,1586 inputs=inputs,1587 **kwargs,1588 )15891590 return CallbackManagerForToolRun(1591 run_id=run_id,1592 handlers=self.handlers,1593 inheritable_handlers=self.inheritable_handlers,1594 parent_run_id=self.parent_run_id,1595 tags=self.tags,1596 inheritable_tags=self.inheritable_tags,1597 metadata=self.metadata,1598 inheritable_metadata=self.inheritable_metadata,1599 )16001601 @override1602 def on_retriever_start(1603 self,1604 serialized: dict[str, Any] | None,1605 query: str,1606 run_id: UUID | None = None,1607 parent_run_id: UUID | None = None,1608 **kwargs: Any,1609 ) -> CallbackManagerForRetrieverRun:1610 """Run when the retriever starts running.16111612 Args:1613 serialized: The serialized retriever.1614 query: The query.1615 run_id: The ID of the run.1616 parent_run_id: The ID of the parent run.1617 **kwargs: Additional keyword arguments.16181619 Returns:1620 The callback manager for the retriever run.1621 """1622 if run_id is None:1623 run_id = uuid7()16241625 handle_event(1626 self.handlers,1627 "on_retriever_start",1628 "ignore_retriever",1629 serialized,1630 query,1631 run_id=run_id,1632 parent_run_id=self.parent_run_id,1633 tags=self.tags,1634 metadata=self.metadata,1635 **kwargs,1636 )16371638 return CallbackManagerForRetrieverRun(1639 run_id=run_id,1640 handlers=self.handlers,1641 inheritable_handlers=self.inheritable_handlers,1642 parent_run_id=self.parent_run_id,1643 tags=self.tags,1644 inheritable_tags=self.inheritable_tags,1645 metadata=self.metadata,1646 inheritable_metadata=self.inheritable_metadata,1647 )16481649 def on_custom_event(1650 self,1651 name: str,1652 data: Any,1653 run_id: UUID | None = None,1654 **kwargs: Any,1655 ) -> None:1656 """Dispatch an adhoc event to the handlers (async version).16571658 This event should NOT be used in any internal LangChain code. The event is meant1659 specifically for users of the library to dispatch custom events that are1660 tailored to their application.16611662 Args:1663 name: The name of the adhoc event.1664 data: The data for the adhoc event.1665 run_id: The ID of the run.16661667 Raises:1668 ValueError: If additional keyword arguments are passed.1669 """1670 if not self.handlers:1671 return1672 if kwargs:1673 msg = (1674 "The dispatcher API does not accept additional keyword arguments."1675 "Please do not pass any additional keyword arguments, instead "1676 "include them in the data field."1677 )1678 raise ValueError(msg)1679 if run_id is None:1680 run_id = uuid7()16811682 handle_event(1683 self.handlers,1684 "on_custom_event",1685 "ignore_custom_event",1686 name,1687 data,1688 run_id=run_id,1689 tags=self.tags,1690 metadata=self.metadata,1691 )16921693 @classmethod1694 def configure(1695 cls,1696 inheritable_callbacks: Callbacks = None,1697 local_callbacks: Callbacks = None,1698 verbose: bool = False, # noqa: FBT001,FBT0021699 inheritable_tags: list[str] | None = None,1700 local_tags: list[str] | None = None,1701 inheritable_metadata: dict[str, Any] | None = None,1702 local_metadata: dict[str, Any] | None = None,1703 *,1704 langsmith_inheritable_metadata: Mapping[str, Any] | None = None,1705 langsmith_inheritable_tags: list[str] | None = None,1706 ) -> CallbackManager:1707 """Configure the callback manager.17081709 Args:1710 inheritable_callbacks: The inheritable callbacks.1711 local_callbacks: The local callbacks.1712 verbose: Whether to enable verbose mode.1713 inheritable_tags: The inheritable tags.1714 local_tags: The local tags.1715 inheritable_metadata: The inheritable metadata.1716 local_metadata: The local metadata.1717 langsmith_inheritable_metadata: Default inheritable metadata applied1718 to any `LangChainTracer` handlers via `set_defaults`.1719 langsmith_inheritable_tags: Default inheritable tags applied to any1720 `LangChainTracer` handlers via `set_defaults`.17211722 Returns:1723 The configured callback manager.1724 """1725 return _configure(1726 cls,1727 inheritable_callbacks,1728 local_callbacks,1729 inheritable_tags,1730 local_tags,1731 inheritable_metadata,1732 local_metadata,1733 verbose=verbose,1734 langsmith_inheritable_metadata=langsmith_inheritable_metadata,1735 langsmith_inheritable_tags=langsmith_inheritable_tags,1736 )173717381739class CallbackManagerForChainGroup(CallbackManager):1740 """Callback manager for the chain group."""17411742 def __init__(1743 self,1744 handlers: list[BaseCallbackHandler],1745 inheritable_handlers: list[BaseCallbackHandler] | None = None,1746 parent_run_id: UUID | None = None,1747 *,1748 parent_run_manager: CallbackManagerForChainRun,1749 **kwargs: Any,1750 ) -> None:1751 """Initialize the callback manager.17521753 Args:1754 handlers: The list of handlers.1755 inheritable_handlers: The list of inheritable handlers.1756 parent_run_id: The ID of the parent run.1757 parent_run_manager: The parent run manager.1758 **kwargs: Additional keyword arguments.17591760 """1761 super().__init__(1762 handlers,1763 inheritable_handlers,1764 parent_run_id,1765 **kwargs,1766 )1767 self.parent_run_manager = parent_run_manager1768 self.ended = False17691770 @override1771 def copy(self) -> CallbackManagerForChainGroup:1772 return self.__class__(1773 handlers=self.handlers.copy(),1774 inheritable_handlers=self.inheritable_handlers.copy(),1775 parent_run_id=self.parent_run_id,1776 tags=self.tags.copy(),1777 inheritable_tags=self.inheritable_tags.copy(),1778 metadata=self.metadata.copy(),1779 inheritable_metadata=self.inheritable_metadata.copy(),1780 parent_run_manager=self.parent_run_manager,1781 )17821783 def merge(1784 self: CallbackManagerForChainGroup, other: BaseCallbackManager1785 ) -> CallbackManagerForChainGroup:1786 """Merge the group callback manager with another callback manager.17871788 Overwrites the merge method in the base class to ensure that the parent run1789 manager is preserved. Keeps the `parent_run_manager` from the current object.17901791 Returns:1792 A copy of the current object with the handlers, tags, and other attributes1793 merged from the other object.17941795 Example:1796 ```python1797 # Merging two callback managers1798 from langchain_core.callbacks.manager import (1799 CallbackManager,1800 trace_as_chain_group,1801 )1802 from langchain_core.callbacks.stdout import StdOutCallbackHandler18031804 manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"])1805 with trace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager:1806 merged_manager = group_manager.merge(manager)1807 print(type(merged_manager))1808 # <class 'langchain_core.callbacks.manager.CallbackManagerForChainGroup'>18091810 print(merged_manager.handlers)1811 # [1812 # <langchain_core.callbacks.stdout.LangChainTracer object at ...>,1813 # <langchain_core.callbacks.streaming_stdout.StdOutCallbackHandler object at ...>,1814 # ]18151816 print(merged_manager.tags)1817 # ['tag2', 'tag1']1818 ```1819 """ # noqa: E5011820 manager = self.__class__(1821 parent_run_id=self.parent_run_id or other.parent_run_id,1822 handlers=[],1823 inheritable_handlers=[],1824 tags=list(set(self.tags + other.tags)),1825 inheritable_tags=list(set(self.inheritable_tags + other.inheritable_tags)),1826 metadata={1827 **self.metadata,1828 **other.metadata,1829 },1830 parent_run_manager=self.parent_run_manager,1831 )18321833 handlers = self.handlers + other.handlers1834 inheritable_handlers = self.inheritable_handlers + other.inheritable_handlers18351836 for handler in handlers:1837 manager.add_handler(handler)18381839 for handler in inheritable_handlers:1840 manager.add_handler(handler, inherit=True)1841 return manager18421843 def on_chain_end(self, outputs: dict[str, Any] | Any, **kwargs: Any) -> None:1844 """Run when traced chain group ends.18451846 Args:1847 outputs: The outputs of the chain.1848 **kwargs: Additional keyword arguments.18491850 """1851 self.ended = True1852 return self.parent_run_manager.on_chain_end(outputs, **kwargs)18531854 def on_chain_error(1855 self,1856 error: BaseException,1857 **kwargs: Any,1858 ) -> None:1859 """Run when chain errors.18601861 Args:1862 error: The error.1863 **kwargs: Additional keyword arguments.18641865 """1866 self.ended = True1867 return self.parent_run_manager.on_chain_error(error, **kwargs)186818691870class AsyncCallbackManager(BaseCallbackManager):1871 """Async callback manager that handles callbacks from LangChain."""18721873 @property1874 def is_async(self) -> bool:1875 """Return whether the handler is async."""1876 return True18771878 async def on_llm_start(1879 self,1880 serialized: dict[str, Any],1881 prompts: list[str],1882 run_id: UUID | None = None,1883 **kwargs: Any,1884 ) -> list[AsyncCallbackManagerForLLMRun]:1885 """Run when LLM starts running.18861887 Args:1888 serialized: The serialized LLM.1889 prompts: The list of prompts.1890 run_id: The ID of the run.1891 **kwargs: Additional keyword arguments.18921893 Returns:1894 The list of async callback managers, one for each LLM run corresponding to1895 each prompt.1896 """1897 inline_tasks = []1898 non_inline_tasks = []1899 inline_handlers = [handler for handler in self.handlers if handler.run_inline]1900 non_inline_handlers = [1901 handler for handler in self.handlers if not handler.run_inline1902 ]1903 managers = []19041905 for prompt in prompts:1906 if run_id is not None:1907 run_id_ = run_id1908 run_id = None1909 else:1910 run_id_ = uuid7()19111912 if inline_handlers:1913 inline_tasks.append(1914 ahandle_event(1915 inline_handlers,1916 "on_llm_start",1917 "ignore_llm",1918 serialized,1919 [prompt],1920 run_id=run_id_,1921 parent_run_id=self.parent_run_id,1922 tags=self.tags,1923 metadata=self.metadata,1924 **kwargs,1925 )1926 )1927 else:1928 non_inline_tasks.append(1929 ahandle_event(1930 non_inline_handlers,1931 "on_llm_start",1932 "ignore_llm",1933 serialized,1934 [prompt],1935 run_id=run_id_,1936 parent_run_id=self.parent_run_id,1937 tags=self.tags,1938 metadata=self.metadata,1939 **kwargs,1940 )1941 )19421943 managers.append(1944 AsyncCallbackManagerForLLMRun(1945 run_id=run_id_,1946 handlers=self.handlers,1947 inheritable_handlers=self.inheritable_handlers,1948 parent_run_id=self.parent_run_id,1949 tags=self.tags,1950 inheritable_tags=self.inheritable_tags,1951 metadata=self.metadata,1952 inheritable_metadata=self.inheritable_metadata,1953 )1954 )19551956 # Run inline tasks sequentially1957 for inline_task in inline_tasks:1958 await inline_task19591960 # Run non-inline tasks concurrently1961 if non_inline_tasks:1962 await asyncio.gather(*non_inline_tasks)19631964 return managers19651966 async def on_chat_model_start(1967 self,1968 serialized: dict[str, Any],1969 messages: list[list[BaseMessage]],1970 run_id: UUID | None = None,1971 **kwargs: Any,1972 ) -> list[AsyncCallbackManagerForLLMRun]:1973 """Async run when LLM starts running.19741975 Args:1976 serialized: The serialized LLM.1977 messages: The list of messages.1978 run_id: The ID of the run.1979 **kwargs: Additional keyword arguments.19801981 Returns:1982 The list of async callback managers, one for each LLM run corresponding to1983 each inner message list.1984 """1985 inline_tasks = []1986 non_inline_tasks = []1987 managers = []19881989 for message_list in messages:1990 if run_id is not None:1991 run_id_ = run_id1992 run_id = None1993 else:1994 run_id_ = uuid7()19951996 for handler in self.handlers:1997 task = ahandle_event(1998 [handler],1999 "on_chat_model_start",2000 "ignore_chat_model",
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.
Generated by searchcode.com · powered by code_get_file + code_get_findings