coco-framework 0.1.0__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.
- coco/__init__.py +3 -0
- coco/agents/__init__.py +9 -0
- coco/agents/_subagent_transformer.py +307 -0
- coco/agents/factory.py +2164 -0
- coco/agents/middleware/__init__.py +100 -0
- coco/agents/middleware/_execution.py +385 -0
- coco/agents/middleware/_redaction.py +454 -0
- coco/agents/middleware/_retry.py +134 -0
- coco/agents/middleware/_trace_policy.py +61 -0
- coco/agents/middleware/context_editing.py +306 -0
- coco/agents/middleware/file_search.py +433 -0
- coco/agents/middleware/human_in_the_loop.py +680 -0
- coco/agents/middleware/internal_call_transformer.py +108 -0
- coco/agents/middleware/model_call_limit.py +267 -0
- coco/agents/middleware/model_fallback.py +417 -0
- coco/agents/middleware/model_retry.py +327 -0
- coco/agents/middleware/pii.py +878 -0
- coco/agents/middleware/provider_tool_search.py +307 -0
- coco/agents/middleware/shell_tool.py +949 -0
- coco/agents/middleware/summarization.py +910 -0
- coco/agents/middleware/todo.py +357 -0
- coco/agents/middleware/tool_call_limit.py +495 -0
- coco/agents/middleware/tool_emulator.py +251 -0
- coco/agents/middleware/tool_error.py +209 -0
- coco/agents/middleware/tool_retry.py +421 -0
- coco/agents/middleware/tool_selection.py +515 -0
- coco/agents/middleware/types.py +2201 -0
- coco/agents/structured_output.py +472 -0
- coco/chat_models/__init__.py +7 -0
- coco/chat_models/base.py +1082 -0
- coco/embeddings/__init__.py +18 -0
- coco/embeddings/base.py +279 -0
- coco/mcp/__init__.py +36 -0
- coco/mcp/adapter.py +245 -0
- coco/mcp/elicitation.py +394 -0
- coco/mcp/tools.py +307 -0
- coco/messages/__init__.py +73 -0
- coco/py.typed +0 -0
- coco/rate_limiters/__init__.py +13 -0
- coco/tools/__init__.py +22 -0
- coco/tools/tool_node.py +20 -0
- coco_anthropic/__init__.py +15 -0
- coco_anthropic/_client_utils.py +81 -0
- coco_anthropic/_compat.py +228 -0
- coco_anthropic/_sdk_compat.py +124 -0
- coco_anthropic/_version.py +3 -0
- coco_anthropic/chat_models.py +3349 -0
- coco_anthropic/data/__init__.py +1 -0
- coco_anthropic/data/_profiles.py +491 -0
- coco_anthropic/data/profile_augmentations.toml +69 -0
- coco_anthropic/experimental.py +140 -0
- coco_anthropic/llms.py +428 -0
- coco_anthropic/middleware/__init__.py +25 -0
- coco_anthropic/middleware/anthropic_tools.py +1197 -0
- coco_anthropic/middleware/bash.py +84 -0
- coco_anthropic/middleware/file_search.py +360 -0
- coco_anthropic/middleware/prompt_caching.py +276 -0
- coco_anthropic/output_parsers.py +93 -0
- coco_anthropic/py.typed +0 -0
- coco_core/__init__.py +20 -0
- coco_core/_api/__init__.py +87 -0
- coco_core/_api/beta_decorator.py +266 -0
- coco_core/_api/deprecation.py +637 -0
- coco_core/_api/internal.py +23 -0
- coco_core/_api/path.py +50 -0
- coco_core/_import_utils.py +41 -0
- coco_core/_protocol.py +625 -0
- coco_core/_security/__init__.py +36 -0
- coco_core/_security/_exceptions.py +9 -0
- coco_core/_security/_policy.py +313 -0
- coco_core/_security/_ssrf_protection.py +155 -0
- coco_core/_security/_transport.py +254 -0
- coco_core/agents.py +258 -0
- coco_core/caches.py +272 -0
- coco_core/callbacks/__init__.py +132 -0
- coco_core/callbacks/base.py +1229 -0
- coco_core/callbacks/file.py +266 -0
- coco_core/callbacks/manager.py +2826 -0
- coco_core/callbacks/stdout.py +123 -0
- coco_core/callbacks/streaming_stdout.py +154 -0
- coco_core/callbacks/usage.py +124 -0
- coco_core/chat_history.py +267 -0
- coco_core/chat_loaders.py +26 -0
- coco_core/chat_sessions.py +19 -0
- coco_core/cross_encoders.py +18 -0
- coco_core/document_loaders/__init__.py +36 -0
- coco_core/document_loaders/base.py +155 -0
- coco_core/document_loaders/blob_loaders.py +38 -0
- coco_core/documents/__init__.py +55 -0
- coco_core/documents/base.py +347 -0
- coco_core/documents/compressor.py +74 -0
- coco_core/documents/transformers.py +79 -0
- coco_core/embeddings/__init__.py +31 -0
- coco_core/embeddings/embeddings.py +78 -0
- coco_core/embeddings/fake.py +129 -0
- coco_core/env.py +22 -0
- coco_core/example_selectors/__init__.py +47 -0
- coco_core/example_selectors/base.py +60 -0
- coco_core/example_selectors/length_based.py +131 -0
- coco_core/example_selectors/semantic_similarity.py +366 -0
- coco_core/exceptions.py +166 -0
- coco_core/globals.py +72 -0
- coco_core/indexing/__init__.py +53 -0
- coco_core/indexing/api.py +954 -0
- coco_core/indexing/base.py +661 -0
- coco_core/indexing/in_memory.py +104 -0
- coco_core/language_models/__init__.py +116 -0
- coco_core/language_models/_compat_bridge.py +844 -0
- coco_core/language_models/_utils.py +343 -0
- coco_core/language_models/base.py +500 -0
- coco_core/language_models/chat_model_stream.py +1525 -0
- coco_core/language_models/chat_models.py +2748 -0
- coco_core/language_models/fake.py +137 -0
- coco_core/language_models/fake_chat_models.py +396 -0
- coco_core/language_models/llms.py +1569 -0
- coco_core/language_models/model_profile.py +183 -0
- coco_core/load/__init__.py +44 -0
- coco_core/load/_validation.py +191 -0
- coco_core/load/dump.py +120 -0
- coco_core/load/load.py +828 -0
- coco_core/load/mapping.py +1097 -0
- coco_core/load/serializable.py +406 -0
- coco_core/messages/__init__.py +198 -0
- coco_core/messages/ai.py +854 -0
- coco_core/messages/base.py +518 -0
- coco_core/messages/block_translators/__init__.py +112 -0
- coco_core/messages/block_translators/anthropic.py +534 -0
- coco_core/messages/block_translators/bedrock.py +108 -0
- coco_core/messages/block_translators/bedrock_converse.py +329 -0
- coco_core/messages/block_translators/coco_v0.py +303 -0
- coco_core/messages/block_translators/google_genai.py +610 -0
- coco_core/messages/block_translators/google_vertexai.py +21 -0
- coco_core/messages/block_translators/groq.py +157 -0
- coco_core/messages/block_translators/openai.py +1089 -0
- coco_core/messages/chat.py +64 -0
- coco_core/messages/content.py +1488 -0
- coco_core/messages/function.py +62 -0
- coco_core/messages/human.py +70 -0
- coco_core/messages/modifier.py +33 -0
- coco_core/messages/system.py +70 -0
- coco_core/messages/tool.py +418 -0
- coco_core/messages/utils.py +2442 -0
- coco_core/output_parsers/__init__.py +101 -0
- coco_core/output_parsers/base.py +361 -0
- coco_core/output_parsers/format_instructions.py +16 -0
- coco_core/output_parsers/json.py +139 -0
- coco_core/output_parsers/list.py +249 -0
- coco_core/output_parsers/openai_functions.py +324 -0
- coco_core/output_parsers/openai_tools.py +383 -0
- coco_core/output_parsers/pydantic.py +141 -0
- coco_core/output_parsers/string.py +63 -0
- coco_core/output_parsers/transform.py +175 -0
- coco_core/output_parsers/xml.py +301 -0
- coco_core/outputs/__init__.py +66 -0
- coco_core/outputs/chat_generation.py +147 -0
- coco_core/outputs/chat_result.py +39 -0
- coco_core/outputs/generation.py +80 -0
- coco_core/outputs/llm_result.py +112 -0
- coco_core/outputs/run_info.py +22 -0
- coco_core/prompt_values.py +161 -0
- coco_core/prompts/__init__.py +101 -0
- coco_core/prompts/base.py +508 -0
- coco_core/prompts/chat.py +1495 -0
- coco_core/prompts/dict.py +177 -0
- coco_core/prompts/few_shot.py +483 -0
- coco_core/prompts/few_shot_with_templates.py +239 -0
- coco_core/prompts/image.py +177 -0
- coco_core/prompts/loading.py +296 -0
- coco_core/prompts/message.py +97 -0
- coco_core/prompts/prompt.py +312 -0
- coco_core/prompts/string.py +399 -0
- coco_core/prompts/structured.py +214 -0
- coco_core/py.typed +0 -0
- coco_core/rate_limiters.py +254 -0
- coco_core/retrievers.py +328 -0
- coco_core/runnables/__init__.py +136 -0
- coco_core/runnables/base.py +6725 -0
- coco_core/runnables/branch.py +457 -0
- coco_core/runnables/config.py +712 -0
- coco_core/runnables/configurable.py +710 -0
- coco_core/runnables/fallbacks.py +663 -0
- coco_core/runnables/graph.py +741 -0
- coco_core/runnables/graph_ascii.py +366 -0
- coco_core/runnables/graph_mermaid.py +503 -0
- coco_core/runnables/graph_png.py +215 -0
- coco_core/runnables/history.py +631 -0
- coco_core/runnables/passthrough.py +849 -0
- coco_core/runnables/retry.py +379 -0
- coco_core/runnables/router.py +239 -0
- coco_core/runnables/schema.py +188 -0
- coco_core/runnables/utils.py +798 -0
- coco_core/stores.py +291 -0
- coco_core/structured_query.py +203 -0
- coco_core/sys_info.py +154 -0
- coco_core/tools/__init__.py +95 -0
- coco_core/tools/base.py +1948 -0
- coco_core/tools/convert.py +497 -0
- coco_core/tools/render.py +67 -0
- coco_core/tools/retriever.py +94 -0
- coco_core/tools/simple.py +208 -0
- coco_core/tools/structured.py +322 -0
- coco_core/tracers/__init__.py +47 -0
- coco_core/tracers/_compat.py +95 -0
- coco_core/tracers/_context.py +337 -0
- coco_core/tracers/_streaming.py +53 -0
- coco_core/tracers/base.py +955 -0
- coco_core/tracers/coco.py +279 -0
- coco_core/tracers/context.py +205 -0
- coco_core/tracers/core.py +766 -0
- coco_core/tracers/event_stream.py +1101 -0
- coco_core/tracers/log_stream.py +765 -0
- coco_core/tracers/memory_stream.py +200 -0
- coco_core/tracers/root_listeners.py +130 -0
- coco_core/tracers/run_collector.py +40 -0
- coco_core/tracers/schemas.py +14 -0
- coco_core/tracers/stdout.py +205 -0
- coco_core/utils/__init__.py +111 -0
- coco_core/utils/_gateway.py +274 -0
- coco_core/utils/_merge.py +218 -0
- coco_core/utils/aiter.py +357 -0
- coco_core/utils/env.py +86 -0
- coco_core/utils/formatting.py +80 -0
- coco_core/utils/function_calling.py +869 -0
- coco_core/utils/html.py +132 -0
- coco_core/utils/image.py +15 -0
- coco_core/utils/input.py +82 -0
- coco_core/utils/interactive_env.py +12 -0
- coco_core/utils/iter.py +229 -0
- coco_core/utils/json.py +230 -0
- coco_core/utils/json_schema.py +273 -0
- coco_core/utils/mustache.py +706 -0
- coco_core/utils/pydantic.py +631 -0
- coco_core/utils/strings.py +69 -0
- coco_core/utils/usage.py +61 -0
- coco_core/utils/utils.py +528 -0
- coco_core/utils/uuid.py +57 -0
- coco_core/vectorstores/__init__.py +53 -0
- coco_core/vectorstores/base.py +1111 -0
- coco_core/vectorstores/in_memory.py +546 -0
- coco_core/vectorstores/utils.py +163 -0
- coco_core/version.py +3 -0
- coco_framework-0.1.0.dist-info/METADATA +184 -0
- coco_framework-0.1.0.dist-info/RECORD +400 -0
- coco_framework-0.1.0.dist-info/WHEEL +4 -0
- coco_framework-0.1.0.dist-info/licenses/LICENSE +24 -0
- coco_framework-0.1.0.dist-info/licenses/NOTICE +15 -0
- coco_graph/_internal/__init__.py +4 -0
- coco_graph/_internal/_cache.py +31 -0
- coco_graph/_internal/_config.py +474 -0
- coco_graph/_internal/_constants.py +140 -0
- coco_graph/_internal/_fields.py +213 -0
- coco_graph/_internal/_future.py +220 -0
- coco_graph/_internal/_pydantic.py +275 -0
- coco_graph/_internal/_queue.py +124 -0
- coco_graph/_internal/_replay.py +90 -0
- coco_graph/_internal/_retry.py +29 -0
- coco_graph/_internal/_runnable.py +969 -0
- coco_graph/_internal/_scratchpad.py +19 -0
- coco_graph/_internal/_serde.py +253 -0
- coco_graph/_internal/_timeout.py +25 -0
- coco_graph/_internal/_typing.py +54 -0
- coco_graph/cache/base/__init__.py +48 -0
- coco_graph/cache/base/py.typed +0 -0
- coco_graph/cache/memory/__init__.py +73 -0
- coco_graph/cache/redis/__init__.py +144 -0
- coco_graph/cache/sqlite/__init__.py +120 -0
- coco_graph/callbacks.py +394 -0
- coco_graph/channels/__init__.py +29 -0
- coco_graph/channels/any_value.py +72 -0
- coco_graph/channels/base.py +121 -0
- coco_graph/channels/binop.py +155 -0
- coco_graph/channels/delta.py +202 -0
- coco_graph/channels/ephemeral_value.py +79 -0
- coco_graph/channels/last_value.py +151 -0
- coco_graph/channels/named_barrier_value.py +167 -0
- coco_graph/channels/topic.py +94 -0
- coco_graph/channels/untracked_value.py +73 -0
- coco_graph/checkpoint/base/__init__.py +861 -0
- coco_graph/checkpoint/base/id.py +109 -0
- coco_graph/checkpoint/base/py.typed +0 -0
- coco_graph/checkpoint/memory/__init__.py +698 -0
- coco_graph/checkpoint/memory/py.typed +0 -0
- coco_graph/checkpoint/postgres/__init__.py +602 -0
- coco_graph/checkpoint/postgres/_ainternal.py +23 -0
- coco_graph/checkpoint/postgres/_internal.py +21 -0
- coco_graph/checkpoint/postgres/aio.py +691 -0
- coco_graph/checkpoint/postgres/base.py +666 -0
- coco_graph/checkpoint/postgres/py.typed +0 -0
- coco_graph/checkpoint/postgres/shallow.py +967 -0
- coco_graph/checkpoint/serde/__init__.py +0 -0
- coco_graph/checkpoint/serde/_msgpack.py +97 -0
- coco_graph/checkpoint/serde/base.py +64 -0
- coco_graph/checkpoint/serde/encrypted.py +80 -0
- coco_graph/checkpoint/serde/event_hooks.py +52 -0
- coco_graph/checkpoint/serde/jsonplus.py +883 -0
- coco_graph/checkpoint/serde/py.typed +0 -0
- coco_graph/checkpoint/serde/types.py +68 -0
- coco_graph/checkpoint/sqlite/__init__.py +645 -0
- coco_graph/checkpoint/sqlite/_delta.py +172 -0
- coco_graph/checkpoint/sqlite/aio.py +738 -0
- coco_graph/checkpoint/sqlite/py.typed +0 -0
- coco_graph/checkpoint/sqlite/utils.py +116 -0
- coco_graph/config.py +196 -0
- coco_graph/constants.py +64 -0
- coco_graph/errors.py +241 -0
- coco_graph/func/__init__.py +620 -0
- coco_graph/graph/__init__.py +12 -0
- coco_graph/graph/_branch.py +225 -0
- coco_graph/graph/_node.py +103 -0
- coco_graph/graph/message.py +437 -0
- coco_graph/graph/state.py +1978 -0
- coco_graph/graph/ui.py +227 -0
- coco_graph/managed/__init__.py +3 -0
- coco_graph/managed/base.py +31 -0
- coco_graph/managed/is_last_step.py +24 -0
- coco_graph/prebuilt/__init__.py +23 -0
- coco_graph/prebuilt/_tool_call_stream.py +117 -0
- coco_graph/prebuilt/_tool_call_transformer.py +165 -0
- coco_graph/prebuilt/chat_agent_executor.py +1015 -0
- coco_graph/prebuilt/interrupt.py +105 -0
- coco_graph/prebuilt/py.typed +0 -0
- coco_graph/prebuilt/tool_node.py +2030 -0
- coco_graph/prebuilt/tool_validator.py +221 -0
- coco_graph/pregel/__init__.py +3 -0
- coco_graph/pregel/_algo.py +1460 -0
- coco_graph/pregel/_call.py +298 -0
- coco_graph/pregel/_checkpoint.py +331 -0
- coco_graph/pregel/_config.py +0 -0
- coco_graph/pregel/_draw.py +294 -0
- coco_graph/pregel/_executor.py +223 -0
- coco_graph/pregel/_io.py +174 -0
- coco_graph/pregel/_log.py +3 -0
- coco_graph/pregel/_loop.py +1988 -0
- coco_graph/pregel/_messages.py +461 -0
- coco_graph/pregel/_read.py +312 -0
- coco_graph/pregel/_retry.py +854 -0
- coco_graph/pregel/_runner.py +941 -0
- coco_graph/pregel/_tools.py +268 -0
- coco_graph/pregel/_utils.py +221 -0
- coco_graph/pregel/_validate.py +120 -0
- coco_graph/pregel/_write.py +192 -0
- coco_graph/pregel/debug.py +302 -0
- coco_graph/pregel/main.py +4364 -0
- coco_graph/pregel/protocol.py +288 -0
- coco_graph/pregel/types.py +38 -0
- coco_graph/py.typed +0 -0
- coco_graph/runtime.py +350 -0
- coco_graph/store/base/__init__.py +1322 -0
- coco_graph/store/base/batch.py +371 -0
- coco_graph/store/base/embed.py +436 -0
- coco_graph/store/base/py.typed +0 -0
- coco_graph/store/memory/__init__.py +592 -0
- coco_graph/store/memory/py.typed +0 -0
- coco_graph/store/postgres/__init__.py +4 -0
- coco_graph/store/postgres/aio.py +592 -0
- coco_graph/store/postgres/base.py +1480 -0
- coco_graph/store/postgres/py.typed +0 -0
- coco_graph/store/sqlite/__init__.py +4 -0
- coco_graph/store/sqlite/aio.py +632 -0
- coco_graph/store/sqlite/base.py +1514 -0
- coco_graph/stream/__init__.py +45 -0
- coco_graph/stream/_convert.py +32 -0
- coco_graph/stream/_mux.py +523 -0
- coco_graph/stream/_types.py +330 -0
- coco_graph/stream/run_stream.py +735 -0
- coco_graph/stream/stream_channel.py +341 -0
- coco_graph/stream/transformers.py +1039 -0
- coco_graph/types.py +1079 -0
- coco_graph/typing.py +48 -0
- coco_graph/utils/__init__.py +1 -0
- coco_graph/utils/config.py +4 -0
- coco_graph/utils/runnable.py +3 -0
- coco_graph/version.py +13 -0
- coco_graph/warnings.py +69 -0
- coco_openai/__init__.py +20 -0
- coco_openai/_compat.py +45 -0
- coco_openai/_version.py +3 -0
- coco_openai/chat_models/__init__.py +6 -0
- coco_openai/chat_models/_client_utils.py +684 -0
- coco_openai/chat_models/_compat.py +525 -0
- coco_openai/chat_models/azure.py +1227 -0
- coco_openai/chat_models/base.py +5654 -0
- coco_openai/chat_models/codex.py +557 -0
- coco_openai/chatgpt_oauth.py +1063 -0
- coco_openai/data/__init__.py +1 -0
- coco_openai/data/_profiles.py +1655 -0
- coco_openai/data/profile_augmentations.toml +127 -0
- coco_openai/embeddings/__init__.py +6 -0
- coco_openai/embeddings/azure.py +240 -0
- coco_openai/embeddings/base.py +820 -0
- coco_openai/llms/__init__.py +6 -0
- coco_openai/llms/azure.py +249 -0
- coco_openai/llms/base.py +919 -0
- coco_openai/middleware/__init__.py +11 -0
- coco_openai/middleware/openai_moderation.py +484 -0
- coco_openai/output_parsers/__init__.py +9 -0
- coco_openai/output_parsers/tools.py +9 -0
- coco_openai/py.typed +0 -0
- coco_openai/tools/__init__.py +5 -0
- coco_openai/tools/custom_tool.py +111 -0
|
@@ -0,0 +1,1229 @@
|
|
|
1
|
+
"""Base callback handler for Coco."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from collections.abc import Sequence
|
|
10
|
+
from uuid import UUID
|
|
11
|
+
|
|
12
|
+
from coco_core._protocol import MessagesData
|
|
13
|
+
from tenacity import RetryCallState
|
|
14
|
+
from typing_extensions import Self
|
|
15
|
+
|
|
16
|
+
from coco_core.agents import AgentAction, AgentFinish
|
|
17
|
+
from coco_core.documents import Document
|
|
18
|
+
from coco_core.messages import BaseMessage
|
|
19
|
+
from coco_core.outputs import ChatGenerationChunk, GenerationChunk, LLMResult
|
|
20
|
+
|
|
21
|
+
_LOGGER = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RetrieverManagerMixin:
|
|
25
|
+
"""Mixin for `Retriever` callbacks."""
|
|
26
|
+
|
|
27
|
+
def on_retriever_error(
|
|
28
|
+
self,
|
|
29
|
+
error: BaseException,
|
|
30
|
+
*,
|
|
31
|
+
run_id: UUID,
|
|
32
|
+
parent_run_id: UUID | None = None,
|
|
33
|
+
**kwargs: Any,
|
|
34
|
+
) -> Any:
|
|
35
|
+
"""Run when `Retriever` errors.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
error: The error that occurred.
|
|
39
|
+
run_id: The ID of the current run.
|
|
40
|
+
parent_run_id: The ID of the parent run.
|
|
41
|
+
**kwargs: Additional keyword arguments.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def on_retriever_end(
|
|
45
|
+
self,
|
|
46
|
+
documents: Sequence[Document],
|
|
47
|
+
*,
|
|
48
|
+
run_id: UUID,
|
|
49
|
+
parent_run_id: UUID | None = None,
|
|
50
|
+
**kwargs: Any,
|
|
51
|
+
) -> Any:
|
|
52
|
+
"""Run when `Retriever` ends running.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
documents: The documents retrieved.
|
|
56
|
+
run_id: The ID of the current run.
|
|
57
|
+
parent_run_id: The ID of the parent run.
|
|
58
|
+
**kwargs: Additional keyword arguments.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class LLMManagerMixin:
|
|
63
|
+
"""Mixin for LLM callbacks."""
|
|
64
|
+
|
|
65
|
+
def on_llm_new_token(
|
|
66
|
+
self,
|
|
67
|
+
token: str | list[str | dict[str, Any]],
|
|
68
|
+
*,
|
|
69
|
+
chunk: GenerationChunk | ChatGenerationChunk | None = None,
|
|
70
|
+
run_id: UUID,
|
|
71
|
+
parent_run_id: UUID | None = None,
|
|
72
|
+
tags: list[str] | None = None,
|
|
73
|
+
**kwargs: Any,
|
|
74
|
+
) -> Any:
|
|
75
|
+
"""Run on new output token.
|
|
76
|
+
|
|
77
|
+
Only available when streaming is enabled.
|
|
78
|
+
|
|
79
|
+
For both chat models and non-chat models (legacy text completion LLMs).
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
token: The new token, or a list of content blocks.
|
|
83
|
+
chunk: The new generated chunk, containing content and other information.
|
|
84
|
+
run_id: The ID of the current run.
|
|
85
|
+
parent_run_id: The ID of the parent run.
|
|
86
|
+
tags: The tags.
|
|
87
|
+
**kwargs: Additional keyword arguments.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def on_llm_end(
|
|
91
|
+
self,
|
|
92
|
+
response: LLMResult,
|
|
93
|
+
*,
|
|
94
|
+
run_id: UUID,
|
|
95
|
+
parent_run_id: UUID | None = None,
|
|
96
|
+
tags: list[str] | None = None,
|
|
97
|
+
**kwargs: Any,
|
|
98
|
+
) -> Any:
|
|
99
|
+
"""Run when LLM ends running.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
response: The response which was generated.
|
|
103
|
+
run_id: The ID of the current run.
|
|
104
|
+
parent_run_id: The ID of the parent run.
|
|
105
|
+
tags: The tags.
|
|
106
|
+
**kwargs: Additional keyword arguments.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def on_llm_error(
|
|
110
|
+
self,
|
|
111
|
+
error: BaseException,
|
|
112
|
+
*,
|
|
113
|
+
run_id: UUID,
|
|
114
|
+
parent_run_id: UUID | None = None,
|
|
115
|
+
tags: list[str] | None = None,
|
|
116
|
+
**kwargs: Any,
|
|
117
|
+
) -> Any:
|
|
118
|
+
"""Run when LLM errors.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
error: The error that occurred.
|
|
122
|
+
run_id: The ID of the current run.
|
|
123
|
+
parent_run_id: The ID of the parent run.
|
|
124
|
+
tags: The tags.
|
|
125
|
+
**kwargs: Additional keyword arguments.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def on_stream_event(
|
|
129
|
+
self,
|
|
130
|
+
event: MessagesData,
|
|
131
|
+
*,
|
|
132
|
+
run_id: UUID,
|
|
133
|
+
parent_run_id: UUID | None = None,
|
|
134
|
+
tags: list[str] | None = None,
|
|
135
|
+
**kwargs: Any,
|
|
136
|
+
) -> Any:
|
|
137
|
+
"""Run on each protocol event from `stream_events(version="v3")`.
|
|
138
|
+
|
|
139
|
+
Also fires for the async equivalent
|
|
140
|
+
(`astream_events(version="v3")`).
|
|
141
|
+
|
|
142
|
+
Fires once per `MessagesData` event — `message-start`, per-block
|
|
143
|
+
`content-block-start` / `content-block-delta` /
|
|
144
|
+
`content-block-finish`, and `message-finish`. Analogous to
|
|
145
|
+
`on_llm_new_token` in v1 streaming, but at event granularity rather
|
|
146
|
+
than chunk: a single chunk can map to multiple events (e.g. a
|
|
147
|
+
`content-block-start` plus its first `content-block-delta`), and
|
|
148
|
+
lifecycle boundaries are explicit.
|
|
149
|
+
|
|
150
|
+
Fires uniformly whether the provider emits events natively via
|
|
151
|
+
`_stream_chat_model_events` or goes through the chunk-to-event
|
|
152
|
+
compat bridge. Observers see the same event stream regardless of
|
|
153
|
+
how the underlying model produces output.
|
|
154
|
+
|
|
155
|
+
Not fired from v1 `stream()` / `astream()`; for those, keep using
|
|
156
|
+
`on_llm_new_token`. Purely additive — `on_chat_model_start`,
|
|
157
|
+
`on_llm_end`, and `on_llm_error` still fire around a v2 call as
|
|
158
|
+
they do around a v1 call.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
event: The protocol event.
|
|
162
|
+
run_id: The ID of the current run.
|
|
163
|
+
parent_run_id: The ID of the parent run.
|
|
164
|
+
tags: The tags.
|
|
165
|
+
**kwargs: Additional keyword arguments.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class ChainManagerMixin:
|
|
170
|
+
"""Mixin for chain callbacks."""
|
|
171
|
+
|
|
172
|
+
def on_chain_end(
|
|
173
|
+
self,
|
|
174
|
+
outputs: dict[str, Any],
|
|
175
|
+
*,
|
|
176
|
+
run_id: UUID,
|
|
177
|
+
parent_run_id: UUID | None = None,
|
|
178
|
+
**kwargs: Any,
|
|
179
|
+
) -> Any:
|
|
180
|
+
"""Run when chain ends running.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
outputs: The outputs of the chain.
|
|
184
|
+
run_id: The ID of the current run.
|
|
185
|
+
parent_run_id: The ID of the parent run.
|
|
186
|
+
**kwargs: Additional keyword arguments.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
def on_chain_error(
|
|
190
|
+
self,
|
|
191
|
+
error: BaseException,
|
|
192
|
+
*,
|
|
193
|
+
run_id: UUID,
|
|
194
|
+
parent_run_id: UUID | None = None,
|
|
195
|
+
**kwargs: Any,
|
|
196
|
+
) -> Any:
|
|
197
|
+
"""Run when chain errors.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
error: The error that occurred.
|
|
201
|
+
run_id: The ID of the current run.
|
|
202
|
+
parent_run_id: The ID of the parent run.
|
|
203
|
+
**kwargs: Additional keyword arguments.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
def on_agent_action(
|
|
207
|
+
self,
|
|
208
|
+
action: AgentAction,
|
|
209
|
+
*,
|
|
210
|
+
run_id: UUID,
|
|
211
|
+
parent_run_id: UUID | None = None,
|
|
212
|
+
**kwargs: Any,
|
|
213
|
+
) -> Any:
|
|
214
|
+
"""Run on agent action.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
action: The agent action.
|
|
218
|
+
run_id: The ID of the current run.
|
|
219
|
+
parent_run_id: The ID of the parent run.
|
|
220
|
+
**kwargs: Additional keyword arguments.
|
|
221
|
+
"""
|
|
222
|
+
|
|
223
|
+
def on_agent_finish(
|
|
224
|
+
self,
|
|
225
|
+
finish: AgentFinish,
|
|
226
|
+
*,
|
|
227
|
+
run_id: UUID,
|
|
228
|
+
parent_run_id: UUID | None = None,
|
|
229
|
+
**kwargs: Any,
|
|
230
|
+
) -> Any:
|
|
231
|
+
"""Run on the agent end.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
finish: The agent finish.
|
|
235
|
+
run_id: The ID of the current run.
|
|
236
|
+
parent_run_id: The ID of the parent run.
|
|
237
|
+
**kwargs: Additional keyword arguments.
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class ToolManagerMixin:
|
|
242
|
+
"""Mixin for tool callbacks."""
|
|
243
|
+
|
|
244
|
+
def on_tool_end(
|
|
245
|
+
self,
|
|
246
|
+
output: Any,
|
|
247
|
+
*,
|
|
248
|
+
run_id: UUID,
|
|
249
|
+
parent_run_id: UUID | None = None,
|
|
250
|
+
**kwargs: Any,
|
|
251
|
+
) -> Any:
|
|
252
|
+
"""Run when the tool ends running.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
output: The output of the tool.
|
|
256
|
+
run_id: The ID of the current run.
|
|
257
|
+
parent_run_id: The ID of the parent run.
|
|
258
|
+
**kwargs: Additional keyword arguments.
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
def on_tool_error(
|
|
262
|
+
self,
|
|
263
|
+
error: BaseException,
|
|
264
|
+
*,
|
|
265
|
+
run_id: UUID,
|
|
266
|
+
parent_run_id: UUID | None = None,
|
|
267
|
+
**kwargs: Any,
|
|
268
|
+
) -> Any:
|
|
269
|
+
"""Run when tool errors.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
error: The error that occurred.
|
|
273
|
+
run_id: The ID of the current run.
|
|
274
|
+
parent_run_id: The ID of the parent run.
|
|
275
|
+
**kwargs: Additional keyword arguments.
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class CallbackManagerMixin:
|
|
280
|
+
"""Mixin for callback manager."""
|
|
281
|
+
|
|
282
|
+
def on_llm_start(
|
|
283
|
+
self,
|
|
284
|
+
serialized: dict[str, Any],
|
|
285
|
+
prompts: list[str],
|
|
286
|
+
*,
|
|
287
|
+
run_id: UUID,
|
|
288
|
+
parent_run_id: UUID | None = None,
|
|
289
|
+
tags: list[str] | None = None,
|
|
290
|
+
metadata: dict[str, Any] | None = None,
|
|
291
|
+
**kwargs: Any,
|
|
292
|
+
) -> Any:
|
|
293
|
+
"""Run when LLM starts running.
|
|
294
|
+
|
|
295
|
+
!!! warning
|
|
296
|
+
|
|
297
|
+
This method is called for non-chat models (regular text completion LLMs). If
|
|
298
|
+
you're implementing a handler for a chat model, you should use
|
|
299
|
+
`on_chat_model_start` instead.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
serialized: The serialized LLM.
|
|
303
|
+
prompts: The prompts.
|
|
304
|
+
run_id: The ID of the current run.
|
|
305
|
+
parent_run_id: The ID of the parent run.
|
|
306
|
+
tags: The tags.
|
|
307
|
+
metadata: The metadata.
|
|
308
|
+
**kwargs: Additional keyword arguments.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
def on_chat_model_start(
|
|
312
|
+
self,
|
|
313
|
+
serialized: dict[str, Any],
|
|
314
|
+
messages: list[list[BaseMessage]],
|
|
315
|
+
*,
|
|
316
|
+
run_id: UUID,
|
|
317
|
+
parent_run_id: UUID | None = None,
|
|
318
|
+
tags: list[str] | None = None,
|
|
319
|
+
metadata: dict[str, Any] | None = None,
|
|
320
|
+
**kwargs: Any,
|
|
321
|
+
) -> Any:
|
|
322
|
+
"""Run when a chat model starts running.
|
|
323
|
+
|
|
324
|
+
!!! warning
|
|
325
|
+
|
|
326
|
+
This method is called for chat models. If you're implementing a handler for
|
|
327
|
+
a non-chat model, you should use `on_llm_start` instead.
|
|
328
|
+
|
|
329
|
+
!!! note
|
|
330
|
+
|
|
331
|
+
When overriding this method, the signature **must** include the two
|
|
332
|
+
required positional arguments `serialized` and `messages`. Avoid
|
|
333
|
+
using `*args` in your override — doing so causes an `IndexError`
|
|
334
|
+
in the fallback path when the callback system converts `messages`
|
|
335
|
+
to prompt strings for `on_llm_start`. Always declare the
|
|
336
|
+
signature explicitly:
|
|
337
|
+
|
|
338
|
+
.. code-block:: python
|
|
339
|
+
|
|
340
|
+
def on_chat_model_start(
|
|
341
|
+
self,
|
|
342
|
+
serialized: dict[str, Any],
|
|
343
|
+
messages: list[list[BaseMessage]],
|
|
344
|
+
**kwargs: Any,
|
|
345
|
+
) -> None:
|
|
346
|
+
raise NotImplementedError # triggers fallback to on_llm_start
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
serialized: The serialized chat model.
|
|
350
|
+
messages: The messages. Must be a list of message lists — this is a
|
|
351
|
+
required positional argument and must be present in any override.
|
|
352
|
+
run_id: The ID of the current run.
|
|
353
|
+
parent_run_id: The ID of the parent run.
|
|
354
|
+
tags: The tags.
|
|
355
|
+
metadata: The metadata.
|
|
356
|
+
**kwargs: Additional keyword arguments.
|
|
357
|
+
"""
|
|
358
|
+
# NotImplementedError is thrown intentionally
|
|
359
|
+
# Callback handler will fall back to on_llm_start if this exception is thrown
|
|
360
|
+
msg = f"{self.__class__.__name__} does not implement `on_chat_model_start`"
|
|
361
|
+
raise NotImplementedError(msg)
|
|
362
|
+
|
|
363
|
+
def on_retriever_start(
|
|
364
|
+
self,
|
|
365
|
+
serialized: dict[str, Any],
|
|
366
|
+
query: str,
|
|
367
|
+
*,
|
|
368
|
+
run_id: UUID,
|
|
369
|
+
parent_run_id: UUID | None = None,
|
|
370
|
+
tags: list[str] | None = None,
|
|
371
|
+
metadata: dict[str, Any] | None = None,
|
|
372
|
+
**kwargs: Any,
|
|
373
|
+
) -> Any:
|
|
374
|
+
"""Run when the `Retriever` starts running.
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
serialized: The serialized `Retriever`.
|
|
378
|
+
query: The query.
|
|
379
|
+
run_id: The ID of the current run.
|
|
380
|
+
parent_run_id: The ID of the parent run.
|
|
381
|
+
tags: The tags.
|
|
382
|
+
metadata: The metadata.
|
|
383
|
+
**kwargs: Additional keyword arguments.
|
|
384
|
+
"""
|
|
385
|
+
|
|
386
|
+
def on_chain_start(
|
|
387
|
+
self,
|
|
388
|
+
serialized: dict[str, Any],
|
|
389
|
+
inputs: dict[str, Any],
|
|
390
|
+
*,
|
|
391
|
+
run_id: UUID,
|
|
392
|
+
parent_run_id: UUID | None = None,
|
|
393
|
+
tags: list[str] | None = None,
|
|
394
|
+
metadata: dict[str, Any] | None = None,
|
|
395
|
+
**kwargs: Any,
|
|
396
|
+
) -> Any:
|
|
397
|
+
"""Run when a chain starts running.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
serialized: The serialized chain.
|
|
401
|
+
inputs: The inputs.
|
|
402
|
+
run_id: The ID of the current run.
|
|
403
|
+
parent_run_id: The ID of the parent run.
|
|
404
|
+
tags: The tags.
|
|
405
|
+
metadata: The metadata.
|
|
406
|
+
**kwargs: Additional keyword arguments.
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
def on_tool_start(
|
|
410
|
+
self,
|
|
411
|
+
serialized: dict[str, Any],
|
|
412
|
+
input_str: str,
|
|
413
|
+
*,
|
|
414
|
+
run_id: UUID,
|
|
415
|
+
parent_run_id: UUID | None = None,
|
|
416
|
+
tags: list[str] | None = None,
|
|
417
|
+
metadata: dict[str, Any] | None = None,
|
|
418
|
+
inputs: dict[str, Any] | None = None,
|
|
419
|
+
**kwargs: Any,
|
|
420
|
+
) -> Any:
|
|
421
|
+
"""Run when the tool starts running.
|
|
422
|
+
|
|
423
|
+
Args:
|
|
424
|
+
serialized: The serialized chain.
|
|
425
|
+
input_str: The input string.
|
|
426
|
+
run_id: The ID of the current run.
|
|
427
|
+
parent_run_id: The ID of the parent run.
|
|
428
|
+
tags: The tags.
|
|
429
|
+
metadata: The metadata.
|
|
430
|
+
inputs: The inputs.
|
|
431
|
+
**kwargs: Additional keyword arguments.
|
|
432
|
+
"""
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
class RunManagerMixin:
|
|
436
|
+
"""Mixin for run manager."""
|
|
437
|
+
|
|
438
|
+
def on_text(
|
|
439
|
+
self,
|
|
440
|
+
text: str,
|
|
441
|
+
*,
|
|
442
|
+
run_id: UUID,
|
|
443
|
+
parent_run_id: UUID | None = None,
|
|
444
|
+
**kwargs: Any,
|
|
445
|
+
) -> Any:
|
|
446
|
+
"""Run on an arbitrary text.
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
text: The text.
|
|
450
|
+
run_id: The ID of the current run.
|
|
451
|
+
parent_run_id: The ID of the parent run.
|
|
452
|
+
**kwargs: Additional keyword arguments.
|
|
453
|
+
"""
|
|
454
|
+
|
|
455
|
+
def on_retry(
|
|
456
|
+
self,
|
|
457
|
+
retry_state: RetryCallState,
|
|
458
|
+
*,
|
|
459
|
+
run_id: UUID,
|
|
460
|
+
parent_run_id: UUID | None = None,
|
|
461
|
+
**kwargs: Any,
|
|
462
|
+
) -> Any:
|
|
463
|
+
"""Run on a retry event.
|
|
464
|
+
|
|
465
|
+
Args:
|
|
466
|
+
retry_state: The retry state.
|
|
467
|
+
run_id: The ID of the current run.
|
|
468
|
+
parent_run_id: The ID of the parent run.
|
|
469
|
+
**kwargs: Additional keyword arguments.
|
|
470
|
+
"""
|
|
471
|
+
|
|
472
|
+
def on_custom_event(
|
|
473
|
+
self,
|
|
474
|
+
name: str,
|
|
475
|
+
data: Any,
|
|
476
|
+
*,
|
|
477
|
+
run_id: UUID,
|
|
478
|
+
tags: list[str] | None = None,
|
|
479
|
+
metadata: dict[str, Any] | None = None,
|
|
480
|
+
**kwargs: Any,
|
|
481
|
+
) -> Any:
|
|
482
|
+
"""Override to define a handler for a custom event.
|
|
483
|
+
|
|
484
|
+
Args:
|
|
485
|
+
name: The name of the custom event.
|
|
486
|
+
data: The data for the custom event.
|
|
487
|
+
|
|
488
|
+
Format will match the format specified by the user.
|
|
489
|
+
run_id: The ID of the run.
|
|
490
|
+
tags: The tags associated with the custom event (includes inherited tags).
|
|
491
|
+
metadata: The metadata associated with the custom event (includes inherited
|
|
492
|
+
metadata).
|
|
493
|
+
"""
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
class BaseCallbackHandler(
|
|
497
|
+
LLMManagerMixin,
|
|
498
|
+
ChainManagerMixin,
|
|
499
|
+
ToolManagerMixin,
|
|
500
|
+
RetrieverManagerMixin,
|
|
501
|
+
CallbackManagerMixin,
|
|
502
|
+
RunManagerMixin,
|
|
503
|
+
):
|
|
504
|
+
"""Base callback handler."""
|
|
505
|
+
|
|
506
|
+
raise_error: bool = False
|
|
507
|
+
"""Whether to raise an error if an exception occurs."""
|
|
508
|
+
|
|
509
|
+
run_inline: bool = False
|
|
510
|
+
"""Whether to run the callback inline."""
|
|
511
|
+
|
|
512
|
+
@property
|
|
513
|
+
def ignore_llm(self) -> bool:
|
|
514
|
+
"""Whether to ignore LLM callbacks."""
|
|
515
|
+
return False
|
|
516
|
+
|
|
517
|
+
@property
|
|
518
|
+
def ignore_retry(self) -> bool:
|
|
519
|
+
"""Whether to ignore retry callbacks."""
|
|
520
|
+
return False
|
|
521
|
+
|
|
522
|
+
@property
|
|
523
|
+
def ignore_chain(self) -> bool:
|
|
524
|
+
"""Whether to ignore chain callbacks."""
|
|
525
|
+
return False
|
|
526
|
+
|
|
527
|
+
@property
|
|
528
|
+
def ignore_agent(self) -> bool:
|
|
529
|
+
"""Whether to ignore agent callbacks."""
|
|
530
|
+
return False
|
|
531
|
+
|
|
532
|
+
@property
|
|
533
|
+
def ignore_retriever(self) -> bool:
|
|
534
|
+
"""Whether to ignore retriever callbacks."""
|
|
535
|
+
return False
|
|
536
|
+
|
|
537
|
+
@property
|
|
538
|
+
def ignore_chat_model(self) -> bool:
|
|
539
|
+
"""Whether to ignore chat model callbacks."""
|
|
540
|
+
return False
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
def ignore_custom_event(self) -> bool:
|
|
544
|
+
"""Ignore custom event."""
|
|
545
|
+
return False
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
class AsyncCallbackHandler(BaseCallbackHandler):
|
|
549
|
+
"""Base async callback handler."""
|
|
550
|
+
|
|
551
|
+
async def on_llm_start(
|
|
552
|
+
self,
|
|
553
|
+
serialized: dict[str, Any],
|
|
554
|
+
prompts: list[str],
|
|
555
|
+
*,
|
|
556
|
+
run_id: UUID,
|
|
557
|
+
parent_run_id: UUID | None = None,
|
|
558
|
+
tags: list[str] | None = None,
|
|
559
|
+
metadata: dict[str, Any] | None = None,
|
|
560
|
+
**kwargs: Any,
|
|
561
|
+
) -> None:
|
|
562
|
+
"""Run when the model starts running.
|
|
563
|
+
|
|
564
|
+
!!! warning
|
|
565
|
+
|
|
566
|
+
This method is called for non-chat models (regular text completion LLMs). If
|
|
567
|
+
you're implementing a handler for a chat model, you should use
|
|
568
|
+
`on_chat_model_start` instead.
|
|
569
|
+
|
|
570
|
+
Args:
|
|
571
|
+
serialized: The serialized LLM.
|
|
572
|
+
prompts: The prompts.
|
|
573
|
+
run_id: The ID of the current run.
|
|
574
|
+
parent_run_id: The ID of the parent run.
|
|
575
|
+
tags: The tags.
|
|
576
|
+
metadata: The metadata.
|
|
577
|
+
**kwargs: Additional keyword arguments.
|
|
578
|
+
"""
|
|
579
|
+
|
|
580
|
+
async def on_chat_model_start(
|
|
581
|
+
self,
|
|
582
|
+
serialized: dict[str, Any],
|
|
583
|
+
messages: list[list[BaseMessage]],
|
|
584
|
+
*,
|
|
585
|
+
run_id: UUID,
|
|
586
|
+
parent_run_id: UUID | None = None,
|
|
587
|
+
tags: list[str] | None = None,
|
|
588
|
+
metadata: dict[str, Any] | None = None,
|
|
589
|
+
**kwargs: Any,
|
|
590
|
+
) -> Any:
|
|
591
|
+
"""Run when a chat model starts running.
|
|
592
|
+
|
|
593
|
+
!!! warning
|
|
594
|
+
|
|
595
|
+
This method is called for chat models. If you're implementing a handler for
|
|
596
|
+
a non-chat model, you should use `on_llm_start` instead.
|
|
597
|
+
|
|
598
|
+
!!! note
|
|
599
|
+
|
|
600
|
+
When overriding this method, the signature **must** include the two
|
|
601
|
+
required positional arguments `serialized` and `messages`. Avoid
|
|
602
|
+
using `*args` in your override — doing so causes an `IndexError`
|
|
603
|
+
in the fallback path when the callback system converts `messages`
|
|
604
|
+
to prompt strings for `on_llm_start`. Always declare the
|
|
605
|
+
signature explicitly:
|
|
606
|
+
|
|
607
|
+
.. code-block:: python
|
|
608
|
+
|
|
609
|
+
async def on_chat_model_start(
|
|
610
|
+
self,
|
|
611
|
+
serialized: dict[str, Any],
|
|
612
|
+
messages: list[list[BaseMessage]],
|
|
613
|
+
**kwargs: Any,
|
|
614
|
+
) -> None:
|
|
615
|
+
raise NotImplementedError # triggers fallback to on_llm_start
|
|
616
|
+
|
|
617
|
+
Args:
|
|
618
|
+
serialized: The serialized chat model.
|
|
619
|
+
messages: The messages. Must be a list of message lists — this is a
|
|
620
|
+
required positional argument and must be present in any override.
|
|
621
|
+
run_id: The ID of the current run.
|
|
622
|
+
parent_run_id: The ID of the parent run.
|
|
623
|
+
tags: The tags.
|
|
624
|
+
metadata: The metadata.
|
|
625
|
+
**kwargs: Additional keyword arguments.
|
|
626
|
+
"""
|
|
627
|
+
# NotImplementedError is thrown intentionally
|
|
628
|
+
# Callback handler will fall back to on_llm_start if this exception is thrown
|
|
629
|
+
msg = f"{self.__class__.__name__} does not implement `on_chat_model_start`"
|
|
630
|
+
raise NotImplementedError(msg)
|
|
631
|
+
|
|
632
|
+
async def on_llm_new_token(
|
|
633
|
+
self,
|
|
634
|
+
token: str | list[str | dict[str, Any]],
|
|
635
|
+
*,
|
|
636
|
+
chunk: GenerationChunk | ChatGenerationChunk | None = None,
|
|
637
|
+
run_id: UUID,
|
|
638
|
+
parent_run_id: UUID | None = None,
|
|
639
|
+
tags: list[str] | None = None,
|
|
640
|
+
**kwargs: Any,
|
|
641
|
+
) -> None:
|
|
642
|
+
"""Run on new output token. Only available when streaming is enabled.
|
|
643
|
+
|
|
644
|
+
For both chat models and non-chat models (legacy text completion LLMs).
|
|
645
|
+
|
|
646
|
+
Args:
|
|
647
|
+
token: The new token, or a list of content blocks.
|
|
648
|
+
chunk: The new generated chunk, containing content and other information.
|
|
649
|
+
run_id: The ID of the current run.
|
|
650
|
+
parent_run_id: The ID of the parent run.
|
|
651
|
+
tags: The tags.
|
|
652
|
+
**kwargs: Additional keyword arguments.
|
|
653
|
+
"""
|
|
654
|
+
|
|
655
|
+
async def on_llm_end(
|
|
656
|
+
self,
|
|
657
|
+
response: LLMResult,
|
|
658
|
+
*,
|
|
659
|
+
run_id: UUID,
|
|
660
|
+
parent_run_id: UUID | None = None,
|
|
661
|
+
tags: list[str] | None = None,
|
|
662
|
+
**kwargs: Any,
|
|
663
|
+
) -> None:
|
|
664
|
+
"""Run when the model ends running.
|
|
665
|
+
|
|
666
|
+
Args:
|
|
667
|
+
response: The response which was generated.
|
|
668
|
+
run_id: The ID of the current run.
|
|
669
|
+
parent_run_id: The ID of the parent run.
|
|
670
|
+
tags: The tags.
|
|
671
|
+
**kwargs: Additional keyword arguments.
|
|
672
|
+
"""
|
|
673
|
+
|
|
674
|
+
async def on_llm_error(
|
|
675
|
+
self,
|
|
676
|
+
error: BaseException,
|
|
677
|
+
*,
|
|
678
|
+
run_id: UUID,
|
|
679
|
+
parent_run_id: UUID | None = None,
|
|
680
|
+
tags: list[str] | None = None,
|
|
681
|
+
**kwargs: Any,
|
|
682
|
+
) -> None:
|
|
683
|
+
"""Run when LLM errors.
|
|
684
|
+
|
|
685
|
+
Args:
|
|
686
|
+
error: The error that occurred.
|
|
687
|
+
run_id: The ID of the current run.
|
|
688
|
+
parent_run_id: The ID of the parent run.
|
|
689
|
+
tags: The tags.
|
|
690
|
+
**kwargs: Additional keyword arguments.
|
|
691
|
+
|
|
692
|
+
- response (LLMResult): The response which was generated before
|
|
693
|
+
the error occurred.
|
|
694
|
+
"""
|
|
695
|
+
|
|
696
|
+
async def on_stream_event(
|
|
697
|
+
self,
|
|
698
|
+
event: MessagesData,
|
|
699
|
+
*,
|
|
700
|
+
run_id: UUID,
|
|
701
|
+
parent_run_id: UUID | None = None,
|
|
702
|
+
tags: list[str] | None = None,
|
|
703
|
+
**kwargs: Any,
|
|
704
|
+
) -> None:
|
|
705
|
+
"""Run on each protocol event produced by `astream_events(version="v3")`.
|
|
706
|
+
|
|
707
|
+
See :meth:`LLMManagerMixin.on_stream_event` for the full contract.
|
|
708
|
+
Fires once per `MessagesData` event at event granularity, uniformly
|
|
709
|
+
across native and compat-bridge providers, and is purely additive
|
|
710
|
+
to the existing `on_chat_model_start` / `on_llm_end` /
|
|
711
|
+
`on_llm_error` callbacks.
|
|
712
|
+
|
|
713
|
+
Args:
|
|
714
|
+
event: The protocol event.
|
|
715
|
+
run_id: The ID of the current run.
|
|
716
|
+
parent_run_id: The ID of the parent run.
|
|
717
|
+
tags: The tags.
|
|
718
|
+
**kwargs: Additional keyword arguments.
|
|
719
|
+
"""
|
|
720
|
+
|
|
721
|
+
async def on_chain_start(
|
|
722
|
+
self,
|
|
723
|
+
serialized: dict[str, Any],
|
|
724
|
+
inputs: dict[str, Any],
|
|
725
|
+
*,
|
|
726
|
+
run_id: UUID,
|
|
727
|
+
parent_run_id: UUID | None = None,
|
|
728
|
+
tags: list[str] | None = None,
|
|
729
|
+
metadata: dict[str, Any] | None = None,
|
|
730
|
+
**kwargs: Any,
|
|
731
|
+
) -> None:
|
|
732
|
+
"""Run when a chain starts running.
|
|
733
|
+
|
|
734
|
+
Args:
|
|
735
|
+
serialized: The serialized chain.
|
|
736
|
+
inputs: The inputs.
|
|
737
|
+
run_id: The ID of the current run.
|
|
738
|
+
parent_run_id: The ID of the parent run.
|
|
739
|
+
tags: The tags.
|
|
740
|
+
metadata: The metadata.
|
|
741
|
+
**kwargs: Additional keyword arguments.
|
|
742
|
+
"""
|
|
743
|
+
|
|
744
|
+
async def on_chain_end(
|
|
745
|
+
self,
|
|
746
|
+
outputs: dict[str, Any],
|
|
747
|
+
*,
|
|
748
|
+
run_id: UUID,
|
|
749
|
+
parent_run_id: UUID | None = None,
|
|
750
|
+
tags: list[str] | None = None,
|
|
751
|
+
**kwargs: Any,
|
|
752
|
+
) -> None:
|
|
753
|
+
"""Run when a chain ends running.
|
|
754
|
+
|
|
755
|
+
Args:
|
|
756
|
+
outputs: The outputs of the chain.
|
|
757
|
+
run_id: The ID of the current run.
|
|
758
|
+
parent_run_id: The ID of the parent run.
|
|
759
|
+
tags: The tags.
|
|
760
|
+
**kwargs: Additional keyword arguments.
|
|
761
|
+
"""
|
|
762
|
+
|
|
763
|
+
async def on_chain_error(
|
|
764
|
+
self,
|
|
765
|
+
error: BaseException,
|
|
766
|
+
*,
|
|
767
|
+
run_id: UUID,
|
|
768
|
+
parent_run_id: UUID | None = None,
|
|
769
|
+
tags: list[str] | None = None,
|
|
770
|
+
**kwargs: Any,
|
|
771
|
+
) -> None:
|
|
772
|
+
"""Run when chain errors.
|
|
773
|
+
|
|
774
|
+
Args:
|
|
775
|
+
error: The error that occurred.
|
|
776
|
+
run_id: The ID of the current run.
|
|
777
|
+
parent_run_id: The ID of the parent run.
|
|
778
|
+
tags: The tags.
|
|
779
|
+
**kwargs: Additional keyword arguments.
|
|
780
|
+
"""
|
|
781
|
+
|
|
782
|
+
async def on_tool_start(
|
|
783
|
+
self,
|
|
784
|
+
serialized: dict[str, Any],
|
|
785
|
+
input_str: str,
|
|
786
|
+
*,
|
|
787
|
+
run_id: UUID,
|
|
788
|
+
parent_run_id: UUID | None = None,
|
|
789
|
+
tags: list[str] | None = None,
|
|
790
|
+
metadata: dict[str, Any] | None = None,
|
|
791
|
+
inputs: dict[str, Any] | None = None,
|
|
792
|
+
**kwargs: Any,
|
|
793
|
+
) -> None:
|
|
794
|
+
"""Run when the tool starts running.
|
|
795
|
+
|
|
796
|
+
Args:
|
|
797
|
+
serialized: The serialized tool.
|
|
798
|
+
input_str: The input string.
|
|
799
|
+
run_id: The ID of the current run.
|
|
800
|
+
parent_run_id: The ID of the parent run.
|
|
801
|
+
tags: The tags.
|
|
802
|
+
metadata: The metadata.
|
|
803
|
+
inputs: The inputs.
|
|
804
|
+
**kwargs: Additional keyword arguments.
|
|
805
|
+
"""
|
|
806
|
+
|
|
807
|
+
async def on_tool_end(
|
|
808
|
+
self,
|
|
809
|
+
output: Any,
|
|
810
|
+
*,
|
|
811
|
+
run_id: UUID,
|
|
812
|
+
parent_run_id: UUID | None = None,
|
|
813
|
+
tags: list[str] | None = None,
|
|
814
|
+
**kwargs: Any,
|
|
815
|
+
) -> None:
|
|
816
|
+
"""Run when the tool ends running.
|
|
817
|
+
|
|
818
|
+
Args:
|
|
819
|
+
output: The output of the tool.
|
|
820
|
+
run_id: The ID of the current run.
|
|
821
|
+
parent_run_id: The ID of the parent run.
|
|
822
|
+
tags: The tags.
|
|
823
|
+
**kwargs: Additional keyword arguments.
|
|
824
|
+
"""
|
|
825
|
+
|
|
826
|
+
async def on_tool_error(
|
|
827
|
+
self,
|
|
828
|
+
error: BaseException,
|
|
829
|
+
*,
|
|
830
|
+
run_id: UUID,
|
|
831
|
+
parent_run_id: UUID | None = None,
|
|
832
|
+
tags: list[str] | None = None,
|
|
833
|
+
**kwargs: Any,
|
|
834
|
+
) -> None:
|
|
835
|
+
"""Run when tool errors.
|
|
836
|
+
|
|
837
|
+
Args:
|
|
838
|
+
error: The error that occurred.
|
|
839
|
+
run_id: The ID of the current run.
|
|
840
|
+
parent_run_id: The ID of the parent run.
|
|
841
|
+
tags: The tags.
|
|
842
|
+
**kwargs: Additional keyword arguments.
|
|
843
|
+
"""
|
|
844
|
+
|
|
845
|
+
async def on_text(
|
|
846
|
+
self,
|
|
847
|
+
text: str,
|
|
848
|
+
*,
|
|
849
|
+
run_id: UUID,
|
|
850
|
+
parent_run_id: UUID | None = None,
|
|
851
|
+
tags: list[str] | None = None,
|
|
852
|
+
**kwargs: Any,
|
|
853
|
+
) -> None:
|
|
854
|
+
"""Run on an arbitrary text.
|
|
855
|
+
|
|
856
|
+
Args:
|
|
857
|
+
text: The text.
|
|
858
|
+
run_id: The ID of the current run.
|
|
859
|
+
parent_run_id: The ID of the parent run.
|
|
860
|
+
tags: The tags.
|
|
861
|
+
**kwargs: Additional keyword arguments.
|
|
862
|
+
"""
|
|
863
|
+
|
|
864
|
+
async def on_retry(
|
|
865
|
+
self,
|
|
866
|
+
retry_state: RetryCallState,
|
|
867
|
+
*,
|
|
868
|
+
run_id: UUID,
|
|
869
|
+
parent_run_id: UUID | None = None,
|
|
870
|
+
**kwargs: Any,
|
|
871
|
+
) -> Any:
|
|
872
|
+
"""Run on a retry event.
|
|
873
|
+
|
|
874
|
+
Args:
|
|
875
|
+
retry_state: The retry state.
|
|
876
|
+
run_id: The ID of the current run.
|
|
877
|
+
parent_run_id: The ID of the parent run.
|
|
878
|
+
**kwargs: Additional keyword arguments.
|
|
879
|
+
"""
|
|
880
|
+
|
|
881
|
+
async def on_agent_action(
|
|
882
|
+
self,
|
|
883
|
+
action: AgentAction,
|
|
884
|
+
*,
|
|
885
|
+
run_id: UUID,
|
|
886
|
+
parent_run_id: UUID | None = None,
|
|
887
|
+
tags: list[str] | None = None,
|
|
888
|
+
**kwargs: Any,
|
|
889
|
+
) -> None:
|
|
890
|
+
"""Run on agent action.
|
|
891
|
+
|
|
892
|
+
Args:
|
|
893
|
+
action: The agent action.
|
|
894
|
+
run_id: The ID of the current run.
|
|
895
|
+
parent_run_id: The ID of the parent run.
|
|
896
|
+
tags: The tags.
|
|
897
|
+
**kwargs: Additional keyword arguments.
|
|
898
|
+
"""
|
|
899
|
+
|
|
900
|
+
async def on_agent_finish(
|
|
901
|
+
self,
|
|
902
|
+
finish: AgentFinish,
|
|
903
|
+
*,
|
|
904
|
+
run_id: UUID,
|
|
905
|
+
parent_run_id: UUID | None = None,
|
|
906
|
+
tags: list[str] | None = None,
|
|
907
|
+
**kwargs: Any,
|
|
908
|
+
) -> None:
|
|
909
|
+
"""Run on the agent end.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
finish: The agent finish.
|
|
913
|
+
run_id: The ID of the current run.
|
|
914
|
+
parent_run_id: The ID of the parent run.
|
|
915
|
+
tags: The tags.
|
|
916
|
+
**kwargs: Additional keyword arguments.
|
|
917
|
+
"""
|
|
918
|
+
|
|
919
|
+
async def on_retriever_start(
|
|
920
|
+
self,
|
|
921
|
+
serialized: dict[str, Any],
|
|
922
|
+
query: str,
|
|
923
|
+
*,
|
|
924
|
+
run_id: UUID,
|
|
925
|
+
parent_run_id: UUID | None = None,
|
|
926
|
+
tags: list[str] | None = None,
|
|
927
|
+
metadata: dict[str, Any] | None = None,
|
|
928
|
+
**kwargs: Any,
|
|
929
|
+
) -> None:
|
|
930
|
+
"""Run on the retriever start.
|
|
931
|
+
|
|
932
|
+
Args:
|
|
933
|
+
serialized: The serialized retriever.
|
|
934
|
+
query: The query.
|
|
935
|
+
run_id: The ID of the current run.
|
|
936
|
+
parent_run_id: The ID of the parent run.
|
|
937
|
+
tags: The tags.
|
|
938
|
+
metadata: The metadata.
|
|
939
|
+
**kwargs: Additional keyword arguments.
|
|
940
|
+
"""
|
|
941
|
+
|
|
942
|
+
async def on_retriever_end(
|
|
943
|
+
self,
|
|
944
|
+
documents: Sequence[Document],
|
|
945
|
+
*,
|
|
946
|
+
run_id: UUID,
|
|
947
|
+
parent_run_id: UUID | None = None,
|
|
948
|
+
tags: list[str] | None = None,
|
|
949
|
+
**kwargs: Any,
|
|
950
|
+
) -> None:
|
|
951
|
+
"""Run on the retriever end.
|
|
952
|
+
|
|
953
|
+
Args:
|
|
954
|
+
documents: The documents retrieved.
|
|
955
|
+
run_id: The ID of the current run.
|
|
956
|
+
parent_run_id: The ID of the parent run.
|
|
957
|
+
tags: The tags.
|
|
958
|
+
**kwargs: Additional keyword arguments.
|
|
959
|
+
"""
|
|
960
|
+
|
|
961
|
+
async def on_retriever_error(
|
|
962
|
+
self,
|
|
963
|
+
error: BaseException,
|
|
964
|
+
*,
|
|
965
|
+
run_id: UUID,
|
|
966
|
+
parent_run_id: UUID | None = None,
|
|
967
|
+
tags: list[str] | None = None,
|
|
968
|
+
**kwargs: Any,
|
|
969
|
+
) -> None:
|
|
970
|
+
"""Run on retriever error.
|
|
971
|
+
|
|
972
|
+
Args:
|
|
973
|
+
error: The error that occurred.
|
|
974
|
+
run_id: The ID of the current run.
|
|
975
|
+
parent_run_id: The ID of the parent run.
|
|
976
|
+
tags: The tags.
|
|
977
|
+
**kwargs: Additional keyword arguments.
|
|
978
|
+
"""
|
|
979
|
+
|
|
980
|
+
async def on_custom_event(
|
|
981
|
+
self,
|
|
982
|
+
name: str,
|
|
983
|
+
data: Any,
|
|
984
|
+
*,
|
|
985
|
+
run_id: UUID,
|
|
986
|
+
tags: list[str] | None = None,
|
|
987
|
+
metadata: dict[str, Any] | None = None,
|
|
988
|
+
**kwargs: Any,
|
|
989
|
+
) -> None:
|
|
990
|
+
"""Override to define a handler for custom events.
|
|
991
|
+
|
|
992
|
+
Args:
|
|
993
|
+
name: The name of the custom event.
|
|
994
|
+
data: The data for the custom event.
|
|
995
|
+
|
|
996
|
+
Format will match the format specified by the user.
|
|
997
|
+
run_id: The ID of the run.
|
|
998
|
+
tags: The tags associated with the custom event (includes inherited tags).
|
|
999
|
+
metadata: The metadata associated with the custom event (includes inherited
|
|
1000
|
+
metadata).
|
|
1001
|
+
"""
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
class BaseCallbackManager(CallbackManagerMixin):
|
|
1005
|
+
"""Base callback manager."""
|
|
1006
|
+
|
|
1007
|
+
def __init__(
|
|
1008
|
+
self,
|
|
1009
|
+
handlers: list[BaseCallbackHandler],
|
|
1010
|
+
inheritable_handlers: list[BaseCallbackHandler] | None = None,
|
|
1011
|
+
parent_run_id: UUID | None = None,
|
|
1012
|
+
*,
|
|
1013
|
+
tags: list[str] | None = None,
|
|
1014
|
+
inheritable_tags: list[str] | None = None,
|
|
1015
|
+
metadata: dict[str, Any] | None = None,
|
|
1016
|
+
inheritable_metadata: dict[str, Any] | None = None,
|
|
1017
|
+
) -> None:
|
|
1018
|
+
"""Initialize callback manager.
|
|
1019
|
+
|
|
1020
|
+
Args:
|
|
1021
|
+
handlers: The handlers.
|
|
1022
|
+
inheritable_handlers: The inheritable handlers.
|
|
1023
|
+
parent_run_id: The parent run ID.
|
|
1024
|
+
tags: The tags.
|
|
1025
|
+
inheritable_tags: The inheritable tags.
|
|
1026
|
+
metadata: The metadata.
|
|
1027
|
+
inheritable_metadata: The inheritable metadata.
|
|
1028
|
+
"""
|
|
1029
|
+
self.handlers: list[BaseCallbackHandler] = handlers
|
|
1030
|
+
self.inheritable_handlers: list[BaseCallbackHandler] = (
|
|
1031
|
+
inheritable_handlers or []
|
|
1032
|
+
)
|
|
1033
|
+
self.parent_run_id: UUID | None = parent_run_id
|
|
1034
|
+
self.tags = tags or []
|
|
1035
|
+
self.inheritable_tags = inheritable_tags or []
|
|
1036
|
+
self.metadata = metadata or {}
|
|
1037
|
+
self.inheritable_metadata = inheritable_metadata or {}
|
|
1038
|
+
|
|
1039
|
+
def copy(self) -> Self:
|
|
1040
|
+
"""Return a copy of the callback manager."""
|
|
1041
|
+
return self.__class__(
|
|
1042
|
+
handlers=self.handlers.copy(),
|
|
1043
|
+
inheritable_handlers=self.inheritable_handlers.copy(),
|
|
1044
|
+
parent_run_id=self.parent_run_id,
|
|
1045
|
+
tags=self.tags.copy(),
|
|
1046
|
+
inheritable_tags=self.inheritable_tags.copy(),
|
|
1047
|
+
metadata=self.metadata.copy(),
|
|
1048
|
+
inheritable_metadata=self.inheritable_metadata.copy(),
|
|
1049
|
+
)
|
|
1050
|
+
|
|
1051
|
+
def merge(self, other: BaseCallbackManager) -> Self:
|
|
1052
|
+
"""Merge the callback manager with another callback manager.
|
|
1053
|
+
|
|
1054
|
+
May be overwritten in subclasses.
|
|
1055
|
+
|
|
1056
|
+
Primarily used internally within `merge_configs`.
|
|
1057
|
+
|
|
1058
|
+
Returns:
|
|
1059
|
+
The merged callback manager of the same type as the current object.
|
|
1060
|
+
|
|
1061
|
+
Example:
|
|
1062
|
+
```python
|
|
1063
|
+
# Merging two callback managers`
|
|
1064
|
+
from coco_core.callbacks.manager import (
|
|
1065
|
+
CallbackManager,
|
|
1066
|
+
trace_as_chain_group,
|
|
1067
|
+
)
|
|
1068
|
+
from coco_core.callbacks.stdout import StdOutCallbackHandler
|
|
1069
|
+
|
|
1070
|
+
manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"])
|
|
1071
|
+
with trace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager:
|
|
1072
|
+
merged_manager = group_manager.merge(manager)
|
|
1073
|
+
print(merged_manager.handlers)
|
|
1074
|
+
# [
|
|
1075
|
+
# <coco_core.callbacks.stdout.StdOutCallbackHandler object at ...>,
|
|
1076
|
+
# <coco_core.callbacks.streaming_stdout.StreamingStdOutCallbackHandler object at ...>,
|
|
1077
|
+
# ]
|
|
1078
|
+
|
|
1079
|
+
print(merged_manager.tags)
|
|
1080
|
+
# ['tag2', 'tag1']
|
|
1081
|
+
```
|
|
1082
|
+
""" # noqa: E501
|
|
1083
|
+
# Combine handlers and inheritable_handlers separately, using sets
|
|
1084
|
+
# to deduplicate (order not preserved)
|
|
1085
|
+
combined_handlers = list(set(self.handlers) | set(other.handlers))
|
|
1086
|
+
combined_inheritable = list(
|
|
1087
|
+
set(self.inheritable_handlers) | set(other.inheritable_handlers)
|
|
1088
|
+
)
|
|
1089
|
+
|
|
1090
|
+
return self.__class__(
|
|
1091
|
+
parent_run_id=self.parent_run_id or other.parent_run_id,
|
|
1092
|
+
handlers=combined_handlers,
|
|
1093
|
+
inheritable_handlers=combined_inheritable,
|
|
1094
|
+
tags=list(set(self.tags + other.tags)),
|
|
1095
|
+
inheritable_tags=list(set(self.inheritable_tags + other.inheritable_tags)),
|
|
1096
|
+
metadata={
|
|
1097
|
+
**self.metadata,
|
|
1098
|
+
**other.metadata,
|
|
1099
|
+
},
|
|
1100
|
+
inheritable_metadata={
|
|
1101
|
+
**self.inheritable_metadata,
|
|
1102
|
+
**other.inheritable_metadata,
|
|
1103
|
+
},
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
@property
|
|
1107
|
+
def is_async(self) -> bool:
|
|
1108
|
+
"""Whether the callback manager is async."""
|
|
1109
|
+
return False
|
|
1110
|
+
|
|
1111
|
+
def add_handler(
|
|
1112
|
+
self,
|
|
1113
|
+
handler: BaseCallbackHandler,
|
|
1114
|
+
inherit: bool = True, # noqa: FBT001,FBT002
|
|
1115
|
+
) -> None:
|
|
1116
|
+
"""Add a handler to the callback manager.
|
|
1117
|
+
|
|
1118
|
+
Args:
|
|
1119
|
+
handler: The handler to add.
|
|
1120
|
+
inherit: Whether to inherit the handler.
|
|
1121
|
+
"""
|
|
1122
|
+
if handler not in self.handlers:
|
|
1123
|
+
self.handlers.append(handler)
|
|
1124
|
+
if inherit and handler not in self.inheritable_handlers:
|
|
1125
|
+
self.inheritable_handlers.append(handler)
|
|
1126
|
+
|
|
1127
|
+
def remove_handler(self, handler: BaseCallbackHandler) -> None:
|
|
1128
|
+
"""Remove a handler from the callback manager.
|
|
1129
|
+
|
|
1130
|
+
Args:
|
|
1131
|
+
handler: The handler to remove.
|
|
1132
|
+
"""
|
|
1133
|
+
if handler in self.handlers:
|
|
1134
|
+
self.handlers.remove(handler)
|
|
1135
|
+
if handler in self.inheritable_handlers:
|
|
1136
|
+
self.inheritable_handlers.remove(handler)
|
|
1137
|
+
|
|
1138
|
+
def set_handlers(
|
|
1139
|
+
self,
|
|
1140
|
+
handlers: list[BaseCallbackHandler],
|
|
1141
|
+
inherit: bool = True, # noqa: FBT001,FBT002
|
|
1142
|
+
) -> None:
|
|
1143
|
+
"""Set handlers as the only handlers on the callback manager.
|
|
1144
|
+
|
|
1145
|
+
Args:
|
|
1146
|
+
handlers: The handlers to set.
|
|
1147
|
+
inherit: Whether to inherit the handlers.
|
|
1148
|
+
"""
|
|
1149
|
+
self.handlers = []
|
|
1150
|
+
self.inheritable_handlers = []
|
|
1151
|
+
for handler in handlers:
|
|
1152
|
+
self.add_handler(handler, inherit=inherit)
|
|
1153
|
+
|
|
1154
|
+
def set_handler(
|
|
1155
|
+
self,
|
|
1156
|
+
handler: BaseCallbackHandler,
|
|
1157
|
+
inherit: bool = True, # noqa: FBT001,FBT002
|
|
1158
|
+
) -> None:
|
|
1159
|
+
"""Set handler as the only handler on the callback manager.
|
|
1160
|
+
|
|
1161
|
+
Args:
|
|
1162
|
+
handler: The handler to set.
|
|
1163
|
+
inherit: Whether to inherit the handler.
|
|
1164
|
+
"""
|
|
1165
|
+
self.set_handlers([handler], inherit=inherit)
|
|
1166
|
+
|
|
1167
|
+
def add_tags(
|
|
1168
|
+
self,
|
|
1169
|
+
tags: list[str],
|
|
1170
|
+
inherit: bool = True, # noqa: FBT001,FBT002
|
|
1171
|
+
) -> None:
|
|
1172
|
+
"""Add tags to the callback manager.
|
|
1173
|
+
|
|
1174
|
+
Args:
|
|
1175
|
+
tags: The tags to add.
|
|
1176
|
+
inherit: Whether to inherit the tags.
|
|
1177
|
+
"""
|
|
1178
|
+
for tag in tags:
|
|
1179
|
+
if tag in self.tags:
|
|
1180
|
+
self.remove_tags([tag])
|
|
1181
|
+
self.tags.extend(tags)
|
|
1182
|
+
if inherit:
|
|
1183
|
+
self.inheritable_tags.extend(tags)
|
|
1184
|
+
|
|
1185
|
+
def remove_tags(self, tags: list[str]) -> None:
|
|
1186
|
+
"""Remove tags from the callback manager.
|
|
1187
|
+
|
|
1188
|
+
Args:
|
|
1189
|
+
tags: The tags to remove.
|
|
1190
|
+
"""
|
|
1191
|
+
for tag in tags:
|
|
1192
|
+
if tag in self.tags:
|
|
1193
|
+
self.tags.remove(tag)
|
|
1194
|
+
if tag in self.inheritable_tags:
|
|
1195
|
+
self.inheritable_tags.remove(tag)
|
|
1196
|
+
|
|
1197
|
+
def add_metadata(
|
|
1198
|
+
self,
|
|
1199
|
+
metadata: dict[str, Any],
|
|
1200
|
+
inherit: bool = True, # noqa: FBT001,FBT002
|
|
1201
|
+
) -> None:
|
|
1202
|
+
"""Add metadata to the callback manager.
|
|
1203
|
+
|
|
1204
|
+
Args:
|
|
1205
|
+
metadata: The metadata to add.
|
|
1206
|
+
inherit: Whether to inherit the metadata.
|
|
1207
|
+
"""
|
|
1208
|
+
from coco_core.runnables.config import ( # noqa: PLC0415
|
|
1209
|
+
_merge_metadata_dicts,
|
|
1210
|
+
)
|
|
1211
|
+
|
|
1212
|
+
self.metadata = _merge_metadata_dicts(self.metadata, metadata)
|
|
1213
|
+
if inherit:
|
|
1214
|
+
self.inheritable_metadata = _merge_metadata_dicts(
|
|
1215
|
+
self.inheritable_metadata, metadata
|
|
1216
|
+
)
|
|
1217
|
+
|
|
1218
|
+
def remove_metadata(self, keys: list[str]) -> None:
|
|
1219
|
+
"""Remove metadata from the callback manager.
|
|
1220
|
+
|
|
1221
|
+
Args:
|
|
1222
|
+
keys: The keys to remove.
|
|
1223
|
+
"""
|
|
1224
|
+
for key in keys:
|
|
1225
|
+
self.metadata.pop(key, None)
|
|
1226
|
+
self.inheritable_metadata.pop(key, None)
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
Callbacks = list[BaseCallbackHandler] | BaseCallbackManager | None
|