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,955 @@
|
|
|
1
|
+
"""Base interfaces for tracing runs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import (
|
|
9
|
+
TYPE_CHECKING,
|
|
10
|
+
Any,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from typing_extensions import override
|
|
14
|
+
|
|
15
|
+
from coco_core.callbacks.base import AsyncCallbackHandler, BaseCallbackHandler
|
|
16
|
+
from coco_core.exceptions import TracerException # noqa: F401
|
|
17
|
+
from coco_core.tracers.core import _TracerCore
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from collections.abc import Sequence
|
|
21
|
+
from uuid import UUID
|
|
22
|
+
|
|
23
|
+
from tenacity import RetryCallState
|
|
24
|
+
|
|
25
|
+
from coco_core.documents import Document
|
|
26
|
+
from coco_core.messages import BaseMessage
|
|
27
|
+
from coco_core.outputs import ChatGenerationChunk, GenerationChunk, LLMResult
|
|
28
|
+
from coco_core.tracers.schemas import Run
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
|
|
34
|
+
"""Base interface for tracers."""
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def _persist_run(self, run: Run) -> None:
|
|
38
|
+
"""Persist a run."""
|
|
39
|
+
|
|
40
|
+
def _start_trace(self, run: Run) -> None:
|
|
41
|
+
"""Start a trace for a run."""
|
|
42
|
+
super()._start_trace(run)
|
|
43
|
+
self._on_run_create(run)
|
|
44
|
+
|
|
45
|
+
def _end_trace(self, run: Run) -> None:
|
|
46
|
+
"""End a trace for a run."""
|
|
47
|
+
if not run.parent_run_id:
|
|
48
|
+
self._persist_run(run)
|
|
49
|
+
self.run_map.pop(str(run.id))
|
|
50
|
+
# If this run's parent was injected from an external tracing context
|
|
51
|
+
# (e.g. a langsmith @traceable), decrement its child refcount and
|
|
52
|
+
# remove it from run_map once the last child is done.
|
|
53
|
+
parent_id = str(run.parent_run_id) if run.parent_run_id else None
|
|
54
|
+
if parent_id and parent_id in self._external_run_ids:
|
|
55
|
+
self._external_run_ids[parent_id] -= 1
|
|
56
|
+
if self._external_run_ids[parent_id] <= 0:
|
|
57
|
+
self.run_map.pop(parent_id, None)
|
|
58
|
+
del self._external_run_ids[parent_id]
|
|
59
|
+
self._on_run_update(run)
|
|
60
|
+
|
|
61
|
+
def on_chat_model_start(
|
|
62
|
+
self,
|
|
63
|
+
serialized: dict[str, Any],
|
|
64
|
+
messages: list[list[BaseMessage]],
|
|
65
|
+
*,
|
|
66
|
+
run_id: UUID,
|
|
67
|
+
tags: list[str] | None = None,
|
|
68
|
+
parent_run_id: UUID | None = None,
|
|
69
|
+
metadata: dict[str, Any] | None = None,
|
|
70
|
+
name: str | None = None,
|
|
71
|
+
**kwargs: Any,
|
|
72
|
+
) -> Run:
|
|
73
|
+
"""Start a trace for a chat model run.
|
|
74
|
+
|
|
75
|
+
Note:
|
|
76
|
+
Naming can be confusing here: there is `on_chat_model_start`, but no
|
|
77
|
+
corresponding `on_chat_model_end` callback. Chat model completion is
|
|
78
|
+
routed through `on_llm_end` / `_on_llm_end`, which are shared with
|
|
79
|
+
text LLM runs.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
serialized: The serialized model.
|
|
83
|
+
messages: The messages to start the chat with.
|
|
84
|
+
run_id: The run ID.
|
|
85
|
+
tags: The tags for the run.
|
|
86
|
+
parent_run_id: The parent run ID.
|
|
87
|
+
metadata: The metadata for the run.
|
|
88
|
+
name: The name of the run.
|
|
89
|
+
**kwargs: Additional arguments.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
The run.
|
|
93
|
+
"""
|
|
94
|
+
chat_model_run = self._create_chat_model_run(
|
|
95
|
+
serialized=serialized,
|
|
96
|
+
messages=messages,
|
|
97
|
+
run_id=run_id,
|
|
98
|
+
parent_run_id=parent_run_id,
|
|
99
|
+
tags=tags,
|
|
100
|
+
metadata=metadata,
|
|
101
|
+
name=name,
|
|
102
|
+
**kwargs,
|
|
103
|
+
)
|
|
104
|
+
self._start_trace(chat_model_run)
|
|
105
|
+
self._on_chat_model_start(chat_model_run)
|
|
106
|
+
return chat_model_run
|
|
107
|
+
|
|
108
|
+
def on_llm_start(
|
|
109
|
+
self,
|
|
110
|
+
serialized: dict[str, Any],
|
|
111
|
+
prompts: list[str],
|
|
112
|
+
*,
|
|
113
|
+
run_id: UUID,
|
|
114
|
+
tags: list[str] | None = None,
|
|
115
|
+
parent_run_id: UUID | None = None,
|
|
116
|
+
metadata: dict[str, Any] | None = None,
|
|
117
|
+
name: str | None = None,
|
|
118
|
+
**kwargs: Any,
|
|
119
|
+
) -> Run:
|
|
120
|
+
"""Start a trace for an LLM run.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
serialized: The serialized model.
|
|
124
|
+
prompts: The prompts to start the LLM with.
|
|
125
|
+
run_id: The run ID.
|
|
126
|
+
tags: The tags for the run.
|
|
127
|
+
parent_run_id: The parent run ID.
|
|
128
|
+
metadata: The metadata for the run.
|
|
129
|
+
name: The name of the run.
|
|
130
|
+
**kwargs: Additional arguments.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
The run.
|
|
134
|
+
"""
|
|
135
|
+
llm_run = self._create_llm_run(
|
|
136
|
+
serialized=serialized,
|
|
137
|
+
prompts=prompts,
|
|
138
|
+
run_id=run_id,
|
|
139
|
+
parent_run_id=parent_run_id,
|
|
140
|
+
tags=tags,
|
|
141
|
+
metadata=metadata,
|
|
142
|
+
name=name,
|
|
143
|
+
**kwargs,
|
|
144
|
+
)
|
|
145
|
+
self._start_trace(llm_run)
|
|
146
|
+
self._on_llm_start(llm_run)
|
|
147
|
+
return llm_run
|
|
148
|
+
|
|
149
|
+
@override
|
|
150
|
+
def on_llm_new_token(
|
|
151
|
+
self,
|
|
152
|
+
token: str | list[str | dict[str, Any]],
|
|
153
|
+
*,
|
|
154
|
+
chunk: GenerationChunk | ChatGenerationChunk | None = None,
|
|
155
|
+
run_id: UUID,
|
|
156
|
+
parent_run_id: UUID | None = None,
|
|
157
|
+
**kwargs: Any,
|
|
158
|
+
) -> Run:
|
|
159
|
+
"""Run on new LLM token.
|
|
160
|
+
|
|
161
|
+
Only available when streaming is enabled.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
token: The token, or a list of content blocks for structured output.
|
|
165
|
+
chunk: The chunk.
|
|
166
|
+
run_id: The run ID.
|
|
167
|
+
parent_run_id: The parent run ID.
|
|
168
|
+
**kwargs: Additional arguments.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
The run.
|
|
172
|
+
"""
|
|
173
|
+
# "chat_model" is only used for the experimental new streaming_events format.
|
|
174
|
+
# This change should not affect any existing tracers.
|
|
175
|
+
llm_run = self._llm_run_with_token_event(
|
|
176
|
+
token=token,
|
|
177
|
+
run_id=run_id,
|
|
178
|
+
chunk=chunk,
|
|
179
|
+
parent_run_id=parent_run_id,
|
|
180
|
+
)
|
|
181
|
+
self._on_llm_new_token(llm_run, token, chunk)
|
|
182
|
+
return llm_run
|
|
183
|
+
|
|
184
|
+
@override
|
|
185
|
+
def on_retry(
|
|
186
|
+
self,
|
|
187
|
+
retry_state: RetryCallState,
|
|
188
|
+
*,
|
|
189
|
+
run_id: UUID,
|
|
190
|
+
**kwargs: Any,
|
|
191
|
+
) -> Run:
|
|
192
|
+
"""Run on retry.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
retry_state: The retry state.
|
|
196
|
+
run_id: The run ID.
|
|
197
|
+
**kwargs: Additional arguments.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
The run.
|
|
201
|
+
"""
|
|
202
|
+
return self._llm_run_with_retry_event(
|
|
203
|
+
retry_state=retry_state,
|
|
204
|
+
run_id=run_id,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
@override
|
|
208
|
+
def on_llm_end(self, response: LLMResult, *, run_id: UUID, **kwargs: Any) -> Run:
|
|
209
|
+
"""End a trace for an LLM or chat model run.
|
|
210
|
+
|
|
211
|
+
Note:
|
|
212
|
+
This is the end callback for both run types. Chat models start with
|
|
213
|
+
`on_chat_model_start`, but there is no `on_chat_model_end`;
|
|
214
|
+
completion is routed here for callback API compatibility.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
response: The response.
|
|
218
|
+
run_id: The run ID.
|
|
219
|
+
**kwargs: Additional arguments.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
The run.
|
|
223
|
+
"""
|
|
224
|
+
# "chat_model" is only used for the experimental new streaming_events format.
|
|
225
|
+
# This change should not affect any existing tracers.
|
|
226
|
+
llm_run = self._complete_llm_run(
|
|
227
|
+
response=response,
|
|
228
|
+
run_id=run_id,
|
|
229
|
+
)
|
|
230
|
+
self._end_trace(llm_run)
|
|
231
|
+
self._on_llm_end(llm_run)
|
|
232
|
+
return llm_run
|
|
233
|
+
|
|
234
|
+
def on_llm_error(
|
|
235
|
+
self,
|
|
236
|
+
error: BaseException,
|
|
237
|
+
*,
|
|
238
|
+
run_id: UUID,
|
|
239
|
+
**kwargs: Any,
|
|
240
|
+
) -> Run:
|
|
241
|
+
"""Handle an error for an LLM run.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
error: The error.
|
|
245
|
+
run_id: The run ID.
|
|
246
|
+
**kwargs: Additional arguments.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
The run.
|
|
250
|
+
"""
|
|
251
|
+
# "chat_model" is only used for the experimental new streaming_events format.
|
|
252
|
+
# This change should not affect any existing tracers.
|
|
253
|
+
llm_run = self._errored_llm_run(
|
|
254
|
+
error=error, run_id=run_id, response=kwargs.pop("response", None)
|
|
255
|
+
)
|
|
256
|
+
self._end_trace(llm_run)
|
|
257
|
+
self._on_llm_error(llm_run)
|
|
258
|
+
return llm_run
|
|
259
|
+
|
|
260
|
+
@override
|
|
261
|
+
def on_chain_start(
|
|
262
|
+
self,
|
|
263
|
+
serialized: dict[str, Any],
|
|
264
|
+
inputs: dict[str, Any],
|
|
265
|
+
*,
|
|
266
|
+
run_id: UUID,
|
|
267
|
+
tags: list[str] | None = None,
|
|
268
|
+
parent_run_id: UUID | None = None,
|
|
269
|
+
metadata: dict[str, Any] | None = None,
|
|
270
|
+
run_type: str | None = None,
|
|
271
|
+
name: str | None = None,
|
|
272
|
+
**kwargs: Any,
|
|
273
|
+
) -> Run:
|
|
274
|
+
"""Start a trace for a chain run.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
serialized: The serialized chain.
|
|
278
|
+
inputs: The inputs for the chain.
|
|
279
|
+
run_id: The run ID.
|
|
280
|
+
tags: The tags for the run.
|
|
281
|
+
parent_run_id: The parent run ID.
|
|
282
|
+
metadata: The metadata for the run.
|
|
283
|
+
run_type: The type of the run.
|
|
284
|
+
name: The name of the run.
|
|
285
|
+
**kwargs: Additional arguments.
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
The run.
|
|
289
|
+
"""
|
|
290
|
+
chain_run = self._create_chain_run(
|
|
291
|
+
serialized=serialized,
|
|
292
|
+
inputs=inputs,
|
|
293
|
+
run_id=run_id,
|
|
294
|
+
tags=tags,
|
|
295
|
+
parent_run_id=parent_run_id,
|
|
296
|
+
metadata=metadata,
|
|
297
|
+
run_type=run_type,
|
|
298
|
+
name=name,
|
|
299
|
+
**kwargs,
|
|
300
|
+
)
|
|
301
|
+
self._start_trace(chain_run)
|
|
302
|
+
self._on_chain_start(chain_run)
|
|
303
|
+
return chain_run
|
|
304
|
+
|
|
305
|
+
@override
|
|
306
|
+
def on_chain_end(
|
|
307
|
+
self,
|
|
308
|
+
outputs: dict[str, Any],
|
|
309
|
+
*,
|
|
310
|
+
run_id: UUID,
|
|
311
|
+
inputs: dict[str, Any] | None = None,
|
|
312
|
+
**kwargs: Any,
|
|
313
|
+
) -> Run:
|
|
314
|
+
"""End a trace for a chain run.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
outputs: The outputs for the chain.
|
|
318
|
+
run_id: The run ID.
|
|
319
|
+
inputs: The inputs for the chain.
|
|
320
|
+
**kwargs: Additional arguments.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
The run.
|
|
324
|
+
"""
|
|
325
|
+
chain_run = self._complete_chain_run(
|
|
326
|
+
outputs=outputs,
|
|
327
|
+
run_id=run_id,
|
|
328
|
+
inputs=inputs,
|
|
329
|
+
)
|
|
330
|
+
self._end_trace(chain_run)
|
|
331
|
+
self._on_chain_end(chain_run)
|
|
332
|
+
return chain_run
|
|
333
|
+
|
|
334
|
+
@override
|
|
335
|
+
def on_chain_error(
|
|
336
|
+
self,
|
|
337
|
+
error: BaseException,
|
|
338
|
+
*,
|
|
339
|
+
inputs: dict[str, Any] | None = None,
|
|
340
|
+
run_id: UUID,
|
|
341
|
+
**kwargs: Any,
|
|
342
|
+
) -> Run:
|
|
343
|
+
"""Handle an error for a chain run.
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
error: The error.
|
|
347
|
+
inputs: The inputs for the chain.
|
|
348
|
+
run_id: The run ID.
|
|
349
|
+
**kwargs: Additional arguments.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
The run.
|
|
353
|
+
"""
|
|
354
|
+
chain_run = self._errored_chain_run(
|
|
355
|
+
error=error,
|
|
356
|
+
run_id=run_id,
|
|
357
|
+
inputs=inputs,
|
|
358
|
+
)
|
|
359
|
+
self._end_trace(chain_run)
|
|
360
|
+
self._on_chain_error(chain_run)
|
|
361
|
+
return chain_run
|
|
362
|
+
|
|
363
|
+
def on_tool_start(
|
|
364
|
+
self,
|
|
365
|
+
serialized: dict[str, Any],
|
|
366
|
+
input_str: str,
|
|
367
|
+
*,
|
|
368
|
+
run_id: UUID,
|
|
369
|
+
tags: list[str] | None = None,
|
|
370
|
+
parent_run_id: UUID | None = None,
|
|
371
|
+
metadata: dict[str, Any] | None = None,
|
|
372
|
+
name: str | None = None,
|
|
373
|
+
inputs: dict[str, Any] | None = None,
|
|
374
|
+
**kwargs: Any,
|
|
375
|
+
) -> Run:
|
|
376
|
+
"""Start a trace for a tool run.
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
serialized: The serialized tool.
|
|
380
|
+
input_str: The input string.
|
|
381
|
+
run_id: The run ID.
|
|
382
|
+
tags: The tags for the run.
|
|
383
|
+
parent_run_id: The parent run ID.
|
|
384
|
+
metadata: The metadata for the run.
|
|
385
|
+
name: The name of the run.
|
|
386
|
+
inputs: The inputs for the tool.
|
|
387
|
+
**kwargs: Additional arguments.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
The run.
|
|
391
|
+
"""
|
|
392
|
+
tool_run = self._create_tool_run(
|
|
393
|
+
serialized=serialized,
|
|
394
|
+
input_str=input_str,
|
|
395
|
+
run_id=run_id,
|
|
396
|
+
tags=tags,
|
|
397
|
+
parent_run_id=parent_run_id,
|
|
398
|
+
metadata=metadata,
|
|
399
|
+
name=name,
|
|
400
|
+
inputs=inputs,
|
|
401
|
+
**kwargs,
|
|
402
|
+
)
|
|
403
|
+
self._start_trace(tool_run)
|
|
404
|
+
self._on_tool_start(tool_run)
|
|
405
|
+
return tool_run
|
|
406
|
+
|
|
407
|
+
@override
|
|
408
|
+
def on_tool_end(self, output: Any, *, run_id: UUID, **kwargs: Any) -> Run:
|
|
409
|
+
"""End a trace for a tool run.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
output: The output for the tool.
|
|
413
|
+
run_id: The run ID.
|
|
414
|
+
**kwargs: Additional arguments.
|
|
415
|
+
|
|
416
|
+
Returns:
|
|
417
|
+
The run.
|
|
418
|
+
"""
|
|
419
|
+
tool_run = self._complete_tool_run(
|
|
420
|
+
output=output,
|
|
421
|
+
run_id=run_id,
|
|
422
|
+
)
|
|
423
|
+
self._end_trace(tool_run)
|
|
424
|
+
self._on_tool_end(tool_run)
|
|
425
|
+
return tool_run
|
|
426
|
+
|
|
427
|
+
@override
|
|
428
|
+
def on_tool_error(
|
|
429
|
+
self,
|
|
430
|
+
error: BaseException,
|
|
431
|
+
*,
|
|
432
|
+
run_id: UUID,
|
|
433
|
+
**kwargs: Any,
|
|
434
|
+
) -> Run:
|
|
435
|
+
"""Handle an error for a tool run.
|
|
436
|
+
|
|
437
|
+
Args:
|
|
438
|
+
error: The error.
|
|
439
|
+
run_id: The run ID.
|
|
440
|
+
**kwargs: Additional arguments.
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
The run.
|
|
444
|
+
"""
|
|
445
|
+
tool_run = self._errored_tool_run(
|
|
446
|
+
error=error,
|
|
447
|
+
run_id=run_id,
|
|
448
|
+
)
|
|
449
|
+
self._end_trace(tool_run)
|
|
450
|
+
self._on_tool_error(tool_run)
|
|
451
|
+
return tool_run
|
|
452
|
+
|
|
453
|
+
def on_retriever_start(
|
|
454
|
+
self,
|
|
455
|
+
serialized: dict[str, Any],
|
|
456
|
+
query: str,
|
|
457
|
+
*,
|
|
458
|
+
run_id: UUID,
|
|
459
|
+
parent_run_id: UUID | None = None,
|
|
460
|
+
tags: list[str] | None = None,
|
|
461
|
+
metadata: dict[str, Any] | None = None,
|
|
462
|
+
name: str | None = None,
|
|
463
|
+
**kwargs: Any,
|
|
464
|
+
) -> Run:
|
|
465
|
+
"""Run when the `Retriever` starts running.
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
serialized: The serialized retriever.
|
|
469
|
+
query: The query.
|
|
470
|
+
run_id: The run ID.
|
|
471
|
+
parent_run_id: The parent run ID.
|
|
472
|
+
tags: The tags for the run.
|
|
473
|
+
metadata: The metadata for the run.
|
|
474
|
+
name: The name of the run.
|
|
475
|
+
**kwargs: Additional arguments.
|
|
476
|
+
|
|
477
|
+
Returns:
|
|
478
|
+
The run.
|
|
479
|
+
"""
|
|
480
|
+
retrieval_run = self._create_retrieval_run(
|
|
481
|
+
serialized=serialized,
|
|
482
|
+
query=query,
|
|
483
|
+
run_id=run_id,
|
|
484
|
+
parent_run_id=parent_run_id,
|
|
485
|
+
tags=tags,
|
|
486
|
+
metadata=metadata,
|
|
487
|
+
name=name,
|
|
488
|
+
**kwargs,
|
|
489
|
+
)
|
|
490
|
+
self._start_trace(retrieval_run)
|
|
491
|
+
self._on_retriever_start(retrieval_run)
|
|
492
|
+
return retrieval_run
|
|
493
|
+
|
|
494
|
+
@override
|
|
495
|
+
def on_retriever_error(
|
|
496
|
+
self,
|
|
497
|
+
error: BaseException,
|
|
498
|
+
*,
|
|
499
|
+
run_id: UUID,
|
|
500
|
+
**kwargs: Any,
|
|
501
|
+
) -> Run:
|
|
502
|
+
"""Run when `Retriever` errors.
|
|
503
|
+
|
|
504
|
+
Args:
|
|
505
|
+
error: The error.
|
|
506
|
+
run_id: The run ID.
|
|
507
|
+
**kwargs: Additional arguments.
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
The run.
|
|
511
|
+
"""
|
|
512
|
+
retrieval_run = self._errored_retrieval_run(
|
|
513
|
+
error=error,
|
|
514
|
+
run_id=run_id,
|
|
515
|
+
)
|
|
516
|
+
self._end_trace(retrieval_run)
|
|
517
|
+
self._on_retriever_error(retrieval_run)
|
|
518
|
+
return retrieval_run
|
|
519
|
+
|
|
520
|
+
@override
|
|
521
|
+
def on_retriever_end(
|
|
522
|
+
self, documents: Sequence[Document], *, run_id: UUID, **kwargs: Any
|
|
523
|
+
) -> Run:
|
|
524
|
+
"""Run when the `Retriever` ends running.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
documents: The documents.
|
|
528
|
+
run_id: The run ID.
|
|
529
|
+
**kwargs: Additional arguments.
|
|
530
|
+
|
|
531
|
+
Returns:
|
|
532
|
+
The run.
|
|
533
|
+
"""
|
|
534
|
+
retrieval_run = self._complete_retrieval_run(
|
|
535
|
+
documents=documents,
|
|
536
|
+
run_id=run_id,
|
|
537
|
+
)
|
|
538
|
+
self._end_trace(retrieval_run)
|
|
539
|
+
self._on_retriever_end(retrieval_run)
|
|
540
|
+
return retrieval_run
|
|
541
|
+
|
|
542
|
+
def __deepcopy__(self, memo: dict[int, Any] | None = None) -> BaseTracer:
|
|
543
|
+
"""Return self."""
|
|
544
|
+
return self
|
|
545
|
+
|
|
546
|
+
def __copy__(self) -> BaseTracer:
|
|
547
|
+
"""Return self."""
|
|
548
|
+
return self
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
class AsyncBaseTracer(_TracerCore, AsyncCallbackHandler, ABC):
|
|
552
|
+
"""Async base interface for tracers."""
|
|
553
|
+
|
|
554
|
+
@abstractmethod
|
|
555
|
+
@override
|
|
556
|
+
async def _persist_run(self, run: Run) -> None:
|
|
557
|
+
"""Persist a run."""
|
|
558
|
+
|
|
559
|
+
@override
|
|
560
|
+
async def _start_trace(self, run: Run) -> None:
|
|
561
|
+
"""Start a trace for a run.
|
|
562
|
+
|
|
563
|
+
Starting a trace will run concurrently with each `_on_[run_type]_start` method.
|
|
564
|
+
No `_on_[run_type]_start` callback should depend on operations in
|
|
565
|
+
`_start_trace`.
|
|
566
|
+
"""
|
|
567
|
+
super()._start_trace(run)
|
|
568
|
+
await self._on_run_create(run)
|
|
569
|
+
|
|
570
|
+
@override
|
|
571
|
+
async def _end_trace(self, run: Run) -> None:
|
|
572
|
+
"""End a trace for a run.
|
|
573
|
+
|
|
574
|
+
Ending a trace will run concurrently with each `_on_[run_type]_end` method.
|
|
575
|
+
No `_on_[run_type]_end` callback should depend on operations in `_end_trace`.
|
|
576
|
+
"""
|
|
577
|
+
if not run.parent_run_id:
|
|
578
|
+
await self._persist_run(run)
|
|
579
|
+
self.run_map.pop(str(run.id))
|
|
580
|
+
# If this run's parent was injected from an external tracing context
|
|
581
|
+
# (e.g. a langsmith @traceable), decrement its child refcount and
|
|
582
|
+
# remove it from run_map once the last child is done.
|
|
583
|
+
parent_id = str(run.parent_run_id) if run.parent_run_id else None
|
|
584
|
+
if parent_id and parent_id in self._external_run_ids:
|
|
585
|
+
self._external_run_ids[parent_id] -= 1
|
|
586
|
+
if self._external_run_ids[parent_id] <= 0:
|
|
587
|
+
self.run_map.pop(parent_id, None)
|
|
588
|
+
del self._external_run_ids[parent_id]
|
|
589
|
+
await self._on_run_update(run)
|
|
590
|
+
|
|
591
|
+
@override
|
|
592
|
+
async def on_chat_model_start(
|
|
593
|
+
self,
|
|
594
|
+
serialized: dict[str, Any],
|
|
595
|
+
messages: list[list[BaseMessage]],
|
|
596
|
+
*,
|
|
597
|
+
run_id: UUID,
|
|
598
|
+
parent_run_id: UUID | None = None,
|
|
599
|
+
tags: list[str] | None = None,
|
|
600
|
+
metadata: dict[str, Any] | None = None,
|
|
601
|
+
name: str | None = None,
|
|
602
|
+
**kwargs: Any,
|
|
603
|
+
) -> Any:
|
|
604
|
+
chat_model_run = self._create_chat_model_run(
|
|
605
|
+
serialized=serialized,
|
|
606
|
+
messages=messages,
|
|
607
|
+
run_id=run_id,
|
|
608
|
+
parent_run_id=parent_run_id,
|
|
609
|
+
tags=tags,
|
|
610
|
+
metadata=metadata,
|
|
611
|
+
name=name,
|
|
612
|
+
**kwargs,
|
|
613
|
+
)
|
|
614
|
+
tasks = [
|
|
615
|
+
self._start_trace(chat_model_run),
|
|
616
|
+
self._on_chat_model_start(chat_model_run),
|
|
617
|
+
]
|
|
618
|
+
await asyncio.gather(*tasks)
|
|
619
|
+
return chat_model_run
|
|
620
|
+
|
|
621
|
+
@override
|
|
622
|
+
async def on_llm_start(
|
|
623
|
+
self,
|
|
624
|
+
serialized: dict[str, Any],
|
|
625
|
+
prompts: list[str],
|
|
626
|
+
*,
|
|
627
|
+
run_id: UUID,
|
|
628
|
+
parent_run_id: UUID | None = None,
|
|
629
|
+
tags: list[str] | None = None,
|
|
630
|
+
metadata: dict[str, Any] | None = None,
|
|
631
|
+
**kwargs: Any,
|
|
632
|
+
) -> None:
|
|
633
|
+
llm_run = self._create_llm_run(
|
|
634
|
+
serialized=serialized,
|
|
635
|
+
prompts=prompts,
|
|
636
|
+
run_id=run_id,
|
|
637
|
+
parent_run_id=parent_run_id,
|
|
638
|
+
tags=tags,
|
|
639
|
+
metadata=metadata,
|
|
640
|
+
**kwargs,
|
|
641
|
+
)
|
|
642
|
+
tasks = [self._start_trace(llm_run), self._on_llm_start(llm_run)]
|
|
643
|
+
await asyncio.gather(*tasks)
|
|
644
|
+
|
|
645
|
+
@override
|
|
646
|
+
async def on_llm_new_token(
|
|
647
|
+
self,
|
|
648
|
+
token: str | list[str | dict[str, Any]],
|
|
649
|
+
*,
|
|
650
|
+
chunk: GenerationChunk | ChatGenerationChunk | None = None,
|
|
651
|
+
run_id: UUID,
|
|
652
|
+
parent_run_id: UUID | None = None,
|
|
653
|
+
**kwargs: Any,
|
|
654
|
+
) -> None:
|
|
655
|
+
llm_run = self._llm_run_with_token_event(
|
|
656
|
+
token=token,
|
|
657
|
+
run_id=run_id,
|
|
658
|
+
chunk=chunk,
|
|
659
|
+
parent_run_id=parent_run_id,
|
|
660
|
+
)
|
|
661
|
+
await self._on_llm_new_token(llm_run, token, chunk)
|
|
662
|
+
|
|
663
|
+
@override
|
|
664
|
+
async def on_retry(
|
|
665
|
+
self,
|
|
666
|
+
retry_state: RetryCallState,
|
|
667
|
+
*,
|
|
668
|
+
run_id: UUID,
|
|
669
|
+
**kwargs: Any,
|
|
670
|
+
) -> None:
|
|
671
|
+
self._llm_run_with_retry_event(
|
|
672
|
+
retry_state=retry_state,
|
|
673
|
+
run_id=run_id,
|
|
674
|
+
)
|
|
675
|
+
|
|
676
|
+
@override
|
|
677
|
+
async def on_llm_end(
|
|
678
|
+
self,
|
|
679
|
+
response: LLMResult,
|
|
680
|
+
*,
|
|
681
|
+
run_id: UUID,
|
|
682
|
+
parent_run_id: UUID | None = None,
|
|
683
|
+
tags: list[str] | None = None,
|
|
684
|
+
**kwargs: Any,
|
|
685
|
+
) -> None:
|
|
686
|
+
"""End a trace for an LLM or chat model run.
|
|
687
|
+
|
|
688
|
+
Note:
|
|
689
|
+
This async callback also handles both run types. Async chat models
|
|
690
|
+
start with `on_chat_model_start`, but there is no
|
|
691
|
+
`on_chat_model_end`; completion is routed here for callback API
|
|
692
|
+
compatibility.
|
|
693
|
+
"""
|
|
694
|
+
llm_run = self._complete_llm_run(
|
|
695
|
+
response=response,
|
|
696
|
+
run_id=run_id,
|
|
697
|
+
)
|
|
698
|
+
tasks = [self._on_llm_end(llm_run), self._end_trace(llm_run)]
|
|
699
|
+
await asyncio.gather(*tasks)
|
|
700
|
+
|
|
701
|
+
@override
|
|
702
|
+
async def on_llm_error(
|
|
703
|
+
self,
|
|
704
|
+
error: BaseException,
|
|
705
|
+
*,
|
|
706
|
+
run_id: UUID,
|
|
707
|
+
parent_run_id: UUID | None = None,
|
|
708
|
+
tags: list[str] | None = None,
|
|
709
|
+
**kwargs: Any,
|
|
710
|
+
) -> None:
|
|
711
|
+
llm_run = self._errored_llm_run(
|
|
712
|
+
error=error,
|
|
713
|
+
run_id=run_id,
|
|
714
|
+
)
|
|
715
|
+
tasks = [self._on_llm_error(llm_run), self._end_trace(llm_run)]
|
|
716
|
+
await asyncio.gather(*tasks)
|
|
717
|
+
|
|
718
|
+
@override
|
|
719
|
+
async def on_chain_start(
|
|
720
|
+
self,
|
|
721
|
+
serialized: dict[str, Any],
|
|
722
|
+
inputs: dict[str, Any],
|
|
723
|
+
*,
|
|
724
|
+
run_id: UUID,
|
|
725
|
+
tags: list[str] | None = None,
|
|
726
|
+
parent_run_id: UUID | None = None,
|
|
727
|
+
metadata: dict[str, Any] | None = None,
|
|
728
|
+
run_type: str | None = None,
|
|
729
|
+
name: str | None = None,
|
|
730
|
+
**kwargs: Any,
|
|
731
|
+
) -> None:
|
|
732
|
+
chain_run = self._create_chain_run(
|
|
733
|
+
serialized=serialized,
|
|
734
|
+
inputs=inputs,
|
|
735
|
+
run_id=run_id,
|
|
736
|
+
tags=tags,
|
|
737
|
+
parent_run_id=parent_run_id,
|
|
738
|
+
metadata=metadata,
|
|
739
|
+
run_type=run_type,
|
|
740
|
+
name=name,
|
|
741
|
+
**kwargs,
|
|
742
|
+
)
|
|
743
|
+
tasks = [self._start_trace(chain_run), self._on_chain_start(chain_run)]
|
|
744
|
+
await asyncio.gather(*tasks)
|
|
745
|
+
|
|
746
|
+
@override
|
|
747
|
+
async def on_chain_end(
|
|
748
|
+
self,
|
|
749
|
+
outputs: dict[str, Any],
|
|
750
|
+
*,
|
|
751
|
+
run_id: UUID,
|
|
752
|
+
inputs: dict[str, Any] | None = None,
|
|
753
|
+
**kwargs: Any,
|
|
754
|
+
) -> None:
|
|
755
|
+
chain_run = self._complete_chain_run(
|
|
756
|
+
outputs=outputs,
|
|
757
|
+
run_id=run_id,
|
|
758
|
+
inputs=inputs,
|
|
759
|
+
)
|
|
760
|
+
tasks = [self._end_trace(chain_run), self._on_chain_end(chain_run)]
|
|
761
|
+
await asyncio.gather(*tasks)
|
|
762
|
+
|
|
763
|
+
@override
|
|
764
|
+
async def on_chain_error(
|
|
765
|
+
self,
|
|
766
|
+
error: BaseException,
|
|
767
|
+
*,
|
|
768
|
+
inputs: dict[str, Any] | None = None,
|
|
769
|
+
run_id: UUID,
|
|
770
|
+
**kwargs: Any,
|
|
771
|
+
) -> None:
|
|
772
|
+
chain_run = self._errored_chain_run(
|
|
773
|
+
error=error,
|
|
774
|
+
inputs=inputs,
|
|
775
|
+
run_id=run_id,
|
|
776
|
+
)
|
|
777
|
+
tasks = [self._end_trace(chain_run), self._on_chain_error(chain_run)]
|
|
778
|
+
await asyncio.gather(*tasks)
|
|
779
|
+
|
|
780
|
+
@override
|
|
781
|
+
async def on_tool_start(
|
|
782
|
+
self,
|
|
783
|
+
serialized: dict[str, Any],
|
|
784
|
+
input_str: str,
|
|
785
|
+
*,
|
|
786
|
+
run_id: UUID,
|
|
787
|
+
tags: list[str] | None = None,
|
|
788
|
+
parent_run_id: UUID | None = None,
|
|
789
|
+
metadata: dict[str, Any] | None = None,
|
|
790
|
+
name: str | None = None,
|
|
791
|
+
inputs: dict[str, Any] | None = None,
|
|
792
|
+
**kwargs: Any,
|
|
793
|
+
) -> None:
|
|
794
|
+
tool_run = self._create_tool_run(
|
|
795
|
+
serialized=serialized,
|
|
796
|
+
input_str=input_str,
|
|
797
|
+
run_id=run_id,
|
|
798
|
+
tags=tags,
|
|
799
|
+
parent_run_id=parent_run_id,
|
|
800
|
+
metadata=metadata,
|
|
801
|
+
inputs=inputs,
|
|
802
|
+
**kwargs,
|
|
803
|
+
)
|
|
804
|
+
tasks = [self._start_trace(tool_run), self._on_tool_start(tool_run)]
|
|
805
|
+
await asyncio.gather(*tasks)
|
|
806
|
+
|
|
807
|
+
@override
|
|
808
|
+
async def on_tool_end(
|
|
809
|
+
self,
|
|
810
|
+
output: Any,
|
|
811
|
+
*,
|
|
812
|
+
run_id: UUID,
|
|
813
|
+
**kwargs: Any,
|
|
814
|
+
) -> None:
|
|
815
|
+
tool_run = self._complete_tool_run(
|
|
816
|
+
output=output,
|
|
817
|
+
run_id=run_id,
|
|
818
|
+
)
|
|
819
|
+
tasks = [self._end_trace(tool_run), self._on_tool_end(tool_run)]
|
|
820
|
+
await asyncio.gather(*tasks)
|
|
821
|
+
|
|
822
|
+
@override
|
|
823
|
+
async def on_tool_error(
|
|
824
|
+
self,
|
|
825
|
+
error: BaseException,
|
|
826
|
+
*,
|
|
827
|
+
run_id: UUID,
|
|
828
|
+
parent_run_id: UUID | None = None,
|
|
829
|
+
tags: list[str] | None = None,
|
|
830
|
+
**kwargs: Any,
|
|
831
|
+
) -> None:
|
|
832
|
+
tool_run = self._errored_tool_run(
|
|
833
|
+
error=error,
|
|
834
|
+
run_id=run_id,
|
|
835
|
+
)
|
|
836
|
+
tasks = [self._end_trace(tool_run), self._on_tool_error(tool_run)]
|
|
837
|
+
await asyncio.gather(*tasks)
|
|
838
|
+
|
|
839
|
+
@override
|
|
840
|
+
async def on_retriever_start(
|
|
841
|
+
self,
|
|
842
|
+
serialized: dict[str, Any],
|
|
843
|
+
query: str,
|
|
844
|
+
*,
|
|
845
|
+
run_id: UUID,
|
|
846
|
+
parent_run_id: UUID | None = None,
|
|
847
|
+
tags: list[str] | None = None,
|
|
848
|
+
metadata: dict[str, Any] | None = None,
|
|
849
|
+
name: str | None = None,
|
|
850
|
+
**kwargs: Any,
|
|
851
|
+
) -> None:
|
|
852
|
+
retriever_run = self._create_retrieval_run(
|
|
853
|
+
serialized=serialized,
|
|
854
|
+
query=query,
|
|
855
|
+
run_id=run_id,
|
|
856
|
+
parent_run_id=parent_run_id,
|
|
857
|
+
tags=tags,
|
|
858
|
+
metadata=metadata,
|
|
859
|
+
name=name,
|
|
860
|
+
)
|
|
861
|
+
tasks = [
|
|
862
|
+
self._start_trace(retriever_run),
|
|
863
|
+
self._on_retriever_start(retriever_run),
|
|
864
|
+
]
|
|
865
|
+
await asyncio.gather(*tasks)
|
|
866
|
+
|
|
867
|
+
@override
|
|
868
|
+
async def on_retriever_error(
|
|
869
|
+
self,
|
|
870
|
+
error: BaseException,
|
|
871
|
+
*,
|
|
872
|
+
run_id: UUID,
|
|
873
|
+
parent_run_id: UUID | None = None,
|
|
874
|
+
tags: list[str] | None = None,
|
|
875
|
+
**kwargs: Any,
|
|
876
|
+
) -> None:
|
|
877
|
+
retrieval_run = self._errored_retrieval_run(
|
|
878
|
+
error=error,
|
|
879
|
+
run_id=run_id,
|
|
880
|
+
)
|
|
881
|
+
tasks = [
|
|
882
|
+
self._end_trace(retrieval_run),
|
|
883
|
+
self._on_retriever_error(retrieval_run),
|
|
884
|
+
]
|
|
885
|
+
await asyncio.gather(*tasks)
|
|
886
|
+
|
|
887
|
+
@override
|
|
888
|
+
async def on_retriever_end(
|
|
889
|
+
self,
|
|
890
|
+
documents: Sequence[Document],
|
|
891
|
+
*,
|
|
892
|
+
run_id: UUID,
|
|
893
|
+
parent_run_id: UUID | None = None,
|
|
894
|
+
tags: list[str] | None = None,
|
|
895
|
+
**kwargs: Any,
|
|
896
|
+
) -> None:
|
|
897
|
+
retrieval_run = self._complete_retrieval_run(
|
|
898
|
+
documents=documents,
|
|
899
|
+
run_id=run_id,
|
|
900
|
+
)
|
|
901
|
+
tasks = [self._end_trace(retrieval_run), self._on_retriever_end(retrieval_run)]
|
|
902
|
+
await asyncio.gather(*tasks)
|
|
903
|
+
|
|
904
|
+
async def _on_run_create(self, run: Run) -> None:
|
|
905
|
+
"""Process a run upon creation."""
|
|
906
|
+
|
|
907
|
+
async def _on_run_update(self, run: Run) -> None:
|
|
908
|
+
"""Process a run upon update."""
|
|
909
|
+
|
|
910
|
+
async def _on_llm_start(self, run: Run) -> None:
|
|
911
|
+
"""Process the LLM Run upon start."""
|
|
912
|
+
|
|
913
|
+
async def _on_llm_end(self, run: Run) -> None:
|
|
914
|
+
"""Process LLM/chat model run completion."""
|
|
915
|
+
|
|
916
|
+
async def _on_llm_error(self, run: Run) -> None:
|
|
917
|
+
"""Process the LLM Run upon error."""
|
|
918
|
+
|
|
919
|
+
async def _on_llm_new_token(
|
|
920
|
+
self,
|
|
921
|
+
run: Run,
|
|
922
|
+
token: str | list[str | dict[str, Any]],
|
|
923
|
+
chunk: GenerationChunk | ChatGenerationChunk | None,
|
|
924
|
+
) -> None:
|
|
925
|
+
"""Process new LLM token."""
|
|
926
|
+
|
|
927
|
+
async def _on_chain_start(self, run: Run) -> None:
|
|
928
|
+
"""Process the Chain Run upon start."""
|
|
929
|
+
|
|
930
|
+
async def _on_chain_end(self, run: Run) -> None:
|
|
931
|
+
"""Process the Chain Run."""
|
|
932
|
+
|
|
933
|
+
async def _on_chain_error(self, run: Run) -> None:
|
|
934
|
+
"""Process the Chain Run upon error."""
|
|
935
|
+
|
|
936
|
+
async def _on_tool_start(self, run: Run) -> None:
|
|
937
|
+
"""Process the Tool Run upon start."""
|
|
938
|
+
|
|
939
|
+
async def _on_tool_end(self, run: Run) -> None:
|
|
940
|
+
"""Process the Tool Run."""
|
|
941
|
+
|
|
942
|
+
async def _on_tool_error(self, run: Run) -> None:
|
|
943
|
+
"""Process the Tool Run upon error."""
|
|
944
|
+
|
|
945
|
+
async def _on_chat_model_start(self, run: Run) -> None:
|
|
946
|
+
"""Process the Chat Model Run upon start."""
|
|
947
|
+
|
|
948
|
+
async def _on_retriever_start(self, run: Run) -> None:
|
|
949
|
+
"""Process the Retriever Run upon start."""
|
|
950
|
+
|
|
951
|
+
async def _on_retriever_end(self, run: Run) -> None:
|
|
952
|
+
"""Process the Retriever Run."""
|
|
953
|
+
|
|
954
|
+
async def _on_retriever_error(self, run: Run) -> None:
|
|
955
|
+
"""Process the Retriever Run upon error."""
|