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.
Files changed (400) hide show
  1. coco/__init__.py +3 -0
  2. coco/agents/__init__.py +9 -0
  3. coco/agents/_subagent_transformer.py +307 -0
  4. coco/agents/factory.py +2164 -0
  5. coco/agents/middleware/__init__.py +100 -0
  6. coco/agents/middleware/_execution.py +385 -0
  7. coco/agents/middleware/_redaction.py +454 -0
  8. coco/agents/middleware/_retry.py +134 -0
  9. coco/agents/middleware/_trace_policy.py +61 -0
  10. coco/agents/middleware/context_editing.py +306 -0
  11. coco/agents/middleware/file_search.py +433 -0
  12. coco/agents/middleware/human_in_the_loop.py +680 -0
  13. coco/agents/middleware/internal_call_transformer.py +108 -0
  14. coco/agents/middleware/model_call_limit.py +267 -0
  15. coco/agents/middleware/model_fallback.py +417 -0
  16. coco/agents/middleware/model_retry.py +327 -0
  17. coco/agents/middleware/pii.py +878 -0
  18. coco/agents/middleware/provider_tool_search.py +307 -0
  19. coco/agents/middleware/shell_tool.py +949 -0
  20. coco/agents/middleware/summarization.py +910 -0
  21. coco/agents/middleware/todo.py +357 -0
  22. coco/agents/middleware/tool_call_limit.py +495 -0
  23. coco/agents/middleware/tool_emulator.py +251 -0
  24. coco/agents/middleware/tool_error.py +209 -0
  25. coco/agents/middleware/tool_retry.py +421 -0
  26. coco/agents/middleware/tool_selection.py +515 -0
  27. coco/agents/middleware/types.py +2201 -0
  28. coco/agents/structured_output.py +472 -0
  29. coco/chat_models/__init__.py +7 -0
  30. coco/chat_models/base.py +1082 -0
  31. coco/embeddings/__init__.py +18 -0
  32. coco/embeddings/base.py +279 -0
  33. coco/mcp/__init__.py +36 -0
  34. coco/mcp/adapter.py +245 -0
  35. coco/mcp/elicitation.py +394 -0
  36. coco/mcp/tools.py +307 -0
  37. coco/messages/__init__.py +73 -0
  38. coco/py.typed +0 -0
  39. coco/rate_limiters/__init__.py +13 -0
  40. coco/tools/__init__.py +22 -0
  41. coco/tools/tool_node.py +20 -0
  42. coco_anthropic/__init__.py +15 -0
  43. coco_anthropic/_client_utils.py +81 -0
  44. coco_anthropic/_compat.py +228 -0
  45. coco_anthropic/_sdk_compat.py +124 -0
  46. coco_anthropic/_version.py +3 -0
  47. coco_anthropic/chat_models.py +3349 -0
  48. coco_anthropic/data/__init__.py +1 -0
  49. coco_anthropic/data/_profiles.py +491 -0
  50. coco_anthropic/data/profile_augmentations.toml +69 -0
  51. coco_anthropic/experimental.py +140 -0
  52. coco_anthropic/llms.py +428 -0
  53. coco_anthropic/middleware/__init__.py +25 -0
  54. coco_anthropic/middleware/anthropic_tools.py +1197 -0
  55. coco_anthropic/middleware/bash.py +84 -0
  56. coco_anthropic/middleware/file_search.py +360 -0
  57. coco_anthropic/middleware/prompt_caching.py +276 -0
  58. coco_anthropic/output_parsers.py +93 -0
  59. coco_anthropic/py.typed +0 -0
  60. coco_core/__init__.py +20 -0
  61. coco_core/_api/__init__.py +87 -0
  62. coco_core/_api/beta_decorator.py +266 -0
  63. coco_core/_api/deprecation.py +637 -0
  64. coco_core/_api/internal.py +23 -0
  65. coco_core/_api/path.py +50 -0
  66. coco_core/_import_utils.py +41 -0
  67. coco_core/_protocol.py +625 -0
  68. coco_core/_security/__init__.py +36 -0
  69. coco_core/_security/_exceptions.py +9 -0
  70. coco_core/_security/_policy.py +313 -0
  71. coco_core/_security/_ssrf_protection.py +155 -0
  72. coco_core/_security/_transport.py +254 -0
  73. coco_core/agents.py +258 -0
  74. coco_core/caches.py +272 -0
  75. coco_core/callbacks/__init__.py +132 -0
  76. coco_core/callbacks/base.py +1229 -0
  77. coco_core/callbacks/file.py +266 -0
  78. coco_core/callbacks/manager.py +2826 -0
  79. coco_core/callbacks/stdout.py +123 -0
  80. coco_core/callbacks/streaming_stdout.py +154 -0
  81. coco_core/callbacks/usage.py +124 -0
  82. coco_core/chat_history.py +267 -0
  83. coco_core/chat_loaders.py +26 -0
  84. coco_core/chat_sessions.py +19 -0
  85. coco_core/cross_encoders.py +18 -0
  86. coco_core/document_loaders/__init__.py +36 -0
  87. coco_core/document_loaders/base.py +155 -0
  88. coco_core/document_loaders/blob_loaders.py +38 -0
  89. coco_core/documents/__init__.py +55 -0
  90. coco_core/documents/base.py +347 -0
  91. coco_core/documents/compressor.py +74 -0
  92. coco_core/documents/transformers.py +79 -0
  93. coco_core/embeddings/__init__.py +31 -0
  94. coco_core/embeddings/embeddings.py +78 -0
  95. coco_core/embeddings/fake.py +129 -0
  96. coco_core/env.py +22 -0
  97. coco_core/example_selectors/__init__.py +47 -0
  98. coco_core/example_selectors/base.py +60 -0
  99. coco_core/example_selectors/length_based.py +131 -0
  100. coco_core/example_selectors/semantic_similarity.py +366 -0
  101. coco_core/exceptions.py +166 -0
  102. coco_core/globals.py +72 -0
  103. coco_core/indexing/__init__.py +53 -0
  104. coco_core/indexing/api.py +954 -0
  105. coco_core/indexing/base.py +661 -0
  106. coco_core/indexing/in_memory.py +104 -0
  107. coco_core/language_models/__init__.py +116 -0
  108. coco_core/language_models/_compat_bridge.py +844 -0
  109. coco_core/language_models/_utils.py +343 -0
  110. coco_core/language_models/base.py +500 -0
  111. coco_core/language_models/chat_model_stream.py +1525 -0
  112. coco_core/language_models/chat_models.py +2748 -0
  113. coco_core/language_models/fake.py +137 -0
  114. coco_core/language_models/fake_chat_models.py +396 -0
  115. coco_core/language_models/llms.py +1569 -0
  116. coco_core/language_models/model_profile.py +183 -0
  117. coco_core/load/__init__.py +44 -0
  118. coco_core/load/_validation.py +191 -0
  119. coco_core/load/dump.py +120 -0
  120. coco_core/load/load.py +828 -0
  121. coco_core/load/mapping.py +1097 -0
  122. coco_core/load/serializable.py +406 -0
  123. coco_core/messages/__init__.py +198 -0
  124. coco_core/messages/ai.py +854 -0
  125. coco_core/messages/base.py +518 -0
  126. coco_core/messages/block_translators/__init__.py +112 -0
  127. coco_core/messages/block_translators/anthropic.py +534 -0
  128. coco_core/messages/block_translators/bedrock.py +108 -0
  129. coco_core/messages/block_translators/bedrock_converse.py +329 -0
  130. coco_core/messages/block_translators/coco_v0.py +303 -0
  131. coco_core/messages/block_translators/google_genai.py +610 -0
  132. coco_core/messages/block_translators/google_vertexai.py +21 -0
  133. coco_core/messages/block_translators/groq.py +157 -0
  134. coco_core/messages/block_translators/openai.py +1089 -0
  135. coco_core/messages/chat.py +64 -0
  136. coco_core/messages/content.py +1488 -0
  137. coco_core/messages/function.py +62 -0
  138. coco_core/messages/human.py +70 -0
  139. coco_core/messages/modifier.py +33 -0
  140. coco_core/messages/system.py +70 -0
  141. coco_core/messages/tool.py +418 -0
  142. coco_core/messages/utils.py +2442 -0
  143. coco_core/output_parsers/__init__.py +101 -0
  144. coco_core/output_parsers/base.py +361 -0
  145. coco_core/output_parsers/format_instructions.py +16 -0
  146. coco_core/output_parsers/json.py +139 -0
  147. coco_core/output_parsers/list.py +249 -0
  148. coco_core/output_parsers/openai_functions.py +324 -0
  149. coco_core/output_parsers/openai_tools.py +383 -0
  150. coco_core/output_parsers/pydantic.py +141 -0
  151. coco_core/output_parsers/string.py +63 -0
  152. coco_core/output_parsers/transform.py +175 -0
  153. coco_core/output_parsers/xml.py +301 -0
  154. coco_core/outputs/__init__.py +66 -0
  155. coco_core/outputs/chat_generation.py +147 -0
  156. coco_core/outputs/chat_result.py +39 -0
  157. coco_core/outputs/generation.py +80 -0
  158. coco_core/outputs/llm_result.py +112 -0
  159. coco_core/outputs/run_info.py +22 -0
  160. coco_core/prompt_values.py +161 -0
  161. coco_core/prompts/__init__.py +101 -0
  162. coco_core/prompts/base.py +508 -0
  163. coco_core/prompts/chat.py +1495 -0
  164. coco_core/prompts/dict.py +177 -0
  165. coco_core/prompts/few_shot.py +483 -0
  166. coco_core/prompts/few_shot_with_templates.py +239 -0
  167. coco_core/prompts/image.py +177 -0
  168. coco_core/prompts/loading.py +296 -0
  169. coco_core/prompts/message.py +97 -0
  170. coco_core/prompts/prompt.py +312 -0
  171. coco_core/prompts/string.py +399 -0
  172. coco_core/prompts/structured.py +214 -0
  173. coco_core/py.typed +0 -0
  174. coco_core/rate_limiters.py +254 -0
  175. coco_core/retrievers.py +328 -0
  176. coco_core/runnables/__init__.py +136 -0
  177. coco_core/runnables/base.py +6725 -0
  178. coco_core/runnables/branch.py +457 -0
  179. coco_core/runnables/config.py +712 -0
  180. coco_core/runnables/configurable.py +710 -0
  181. coco_core/runnables/fallbacks.py +663 -0
  182. coco_core/runnables/graph.py +741 -0
  183. coco_core/runnables/graph_ascii.py +366 -0
  184. coco_core/runnables/graph_mermaid.py +503 -0
  185. coco_core/runnables/graph_png.py +215 -0
  186. coco_core/runnables/history.py +631 -0
  187. coco_core/runnables/passthrough.py +849 -0
  188. coco_core/runnables/retry.py +379 -0
  189. coco_core/runnables/router.py +239 -0
  190. coco_core/runnables/schema.py +188 -0
  191. coco_core/runnables/utils.py +798 -0
  192. coco_core/stores.py +291 -0
  193. coco_core/structured_query.py +203 -0
  194. coco_core/sys_info.py +154 -0
  195. coco_core/tools/__init__.py +95 -0
  196. coco_core/tools/base.py +1948 -0
  197. coco_core/tools/convert.py +497 -0
  198. coco_core/tools/render.py +67 -0
  199. coco_core/tools/retriever.py +94 -0
  200. coco_core/tools/simple.py +208 -0
  201. coco_core/tools/structured.py +322 -0
  202. coco_core/tracers/__init__.py +47 -0
  203. coco_core/tracers/_compat.py +95 -0
  204. coco_core/tracers/_context.py +337 -0
  205. coco_core/tracers/_streaming.py +53 -0
  206. coco_core/tracers/base.py +955 -0
  207. coco_core/tracers/coco.py +279 -0
  208. coco_core/tracers/context.py +205 -0
  209. coco_core/tracers/core.py +766 -0
  210. coco_core/tracers/event_stream.py +1101 -0
  211. coco_core/tracers/log_stream.py +765 -0
  212. coco_core/tracers/memory_stream.py +200 -0
  213. coco_core/tracers/root_listeners.py +130 -0
  214. coco_core/tracers/run_collector.py +40 -0
  215. coco_core/tracers/schemas.py +14 -0
  216. coco_core/tracers/stdout.py +205 -0
  217. coco_core/utils/__init__.py +111 -0
  218. coco_core/utils/_gateway.py +274 -0
  219. coco_core/utils/_merge.py +218 -0
  220. coco_core/utils/aiter.py +357 -0
  221. coco_core/utils/env.py +86 -0
  222. coco_core/utils/formatting.py +80 -0
  223. coco_core/utils/function_calling.py +869 -0
  224. coco_core/utils/html.py +132 -0
  225. coco_core/utils/image.py +15 -0
  226. coco_core/utils/input.py +82 -0
  227. coco_core/utils/interactive_env.py +12 -0
  228. coco_core/utils/iter.py +229 -0
  229. coco_core/utils/json.py +230 -0
  230. coco_core/utils/json_schema.py +273 -0
  231. coco_core/utils/mustache.py +706 -0
  232. coco_core/utils/pydantic.py +631 -0
  233. coco_core/utils/strings.py +69 -0
  234. coco_core/utils/usage.py +61 -0
  235. coco_core/utils/utils.py +528 -0
  236. coco_core/utils/uuid.py +57 -0
  237. coco_core/vectorstores/__init__.py +53 -0
  238. coco_core/vectorstores/base.py +1111 -0
  239. coco_core/vectorstores/in_memory.py +546 -0
  240. coco_core/vectorstores/utils.py +163 -0
  241. coco_core/version.py +3 -0
  242. coco_framework-0.1.0.dist-info/METADATA +184 -0
  243. coco_framework-0.1.0.dist-info/RECORD +400 -0
  244. coco_framework-0.1.0.dist-info/WHEEL +4 -0
  245. coco_framework-0.1.0.dist-info/licenses/LICENSE +24 -0
  246. coco_framework-0.1.0.dist-info/licenses/NOTICE +15 -0
  247. coco_graph/_internal/__init__.py +4 -0
  248. coco_graph/_internal/_cache.py +31 -0
  249. coco_graph/_internal/_config.py +474 -0
  250. coco_graph/_internal/_constants.py +140 -0
  251. coco_graph/_internal/_fields.py +213 -0
  252. coco_graph/_internal/_future.py +220 -0
  253. coco_graph/_internal/_pydantic.py +275 -0
  254. coco_graph/_internal/_queue.py +124 -0
  255. coco_graph/_internal/_replay.py +90 -0
  256. coco_graph/_internal/_retry.py +29 -0
  257. coco_graph/_internal/_runnable.py +969 -0
  258. coco_graph/_internal/_scratchpad.py +19 -0
  259. coco_graph/_internal/_serde.py +253 -0
  260. coco_graph/_internal/_timeout.py +25 -0
  261. coco_graph/_internal/_typing.py +54 -0
  262. coco_graph/cache/base/__init__.py +48 -0
  263. coco_graph/cache/base/py.typed +0 -0
  264. coco_graph/cache/memory/__init__.py +73 -0
  265. coco_graph/cache/redis/__init__.py +144 -0
  266. coco_graph/cache/sqlite/__init__.py +120 -0
  267. coco_graph/callbacks.py +394 -0
  268. coco_graph/channels/__init__.py +29 -0
  269. coco_graph/channels/any_value.py +72 -0
  270. coco_graph/channels/base.py +121 -0
  271. coco_graph/channels/binop.py +155 -0
  272. coco_graph/channels/delta.py +202 -0
  273. coco_graph/channels/ephemeral_value.py +79 -0
  274. coco_graph/channels/last_value.py +151 -0
  275. coco_graph/channels/named_barrier_value.py +167 -0
  276. coco_graph/channels/topic.py +94 -0
  277. coco_graph/channels/untracked_value.py +73 -0
  278. coco_graph/checkpoint/base/__init__.py +861 -0
  279. coco_graph/checkpoint/base/id.py +109 -0
  280. coco_graph/checkpoint/base/py.typed +0 -0
  281. coco_graph/checkpoint/memory/__init__.py +698 -0
  282. coco_graph/checkpoint/memory/py.typed +0 -0
  283. coco_graph/checkpoint/postgres/__init__.py +602 -0
  284. coco_graph/checkpoint/postgres/_ainternal.py +23 -0
  285. coco_graph/checkpoint/postgres/_internal.py +21 -0
  286. coco_graph/checkpoint/postgres/aio.py +691 -0
  287. coco_graph/checkpoint/postgres/base.py +666 -0
  288. coco_graph/checkpoint/postgres/py.typed +0 -0
  289. coco_graph/checkpoint/postgres/shallow.py +967 -0
  290. coco_graph/checkpoint/serde/__init__.py +0 -0
  291. coco_graph/checkpoint/serde/_msgpack.py +97 -0
  292. coco_graph/checkpoint/serde/base.py +64 -0
  293. coco_graph/checkpoint/serde/encrypted.py +80 -0
  294. coco_graph/checkpoint/serde/event_hooks.py +52 -0
  295. coco_graph/checkpoint/serde/jsonplus.py +883 -0
  296. coco_graph/checkpoint/serde/py.typed +0 -0
  297. coco_graph/checkpoint/serde/types.py +68 -0
  298. coco_graph/checkpoint/sqlite/__init__.py +645 -0
  299. coco_graph/checkpoint/sqlite/_delta.py +172 -0
  300. coco_graph/checkpoint/sqlite/aio.py +738 -0
  301. coco_graph/checkpoint/sqlite/py.typed +0 -0
  302. coco_graph/checkpoint/sqlite/utils.py +116 -0
  303. coco_graph/config.py +196 -0
  304. coco_graph/constants.py +64 -0
  305. coco_graph/errors.py +241 -0
  306. coco_graph/func/__init__.py +620 -0
  307. coco_graph/graph/__init__.py +12 -0
  308. coco_graph/graph/_branch.py +225 -0
  309. coco_graph/graph/_node.py +103 -0
  310. coco_graph/graph/message.py +437 -0
  311. coco_graph/graph/state.py +1978 -0
  312. coco_graph/graph/ui.py +227 -0
  313. coco_graph/managed/__init__.py +3 -0
  314. coco_graph/managed/base.py +31 -0
  315. coco_graph/managed/is_last_step.py +24 -0
  316. coco_graph/prebuilt/__init__.py +23 -0
  317. coco_graph/prebuilt/_tool_call_stream.py +117 -0
  318. coco_graph/prebuilt/_tool_call_transformer.py +165 -0
  319. coco_graph/prebuilt/chat_agent_executor.py +1015 -0
  320. coco_graph/prebuilt/interrupt.py +105 -0
  321. coco_graph/prebuilt/py.typed +0 -0
  322. coco_graph/prebuilt/tool_node.py +2030 -0
  323. coco_graph/prebuilt/tool_validator.py +221 -0
  324. coco_graph/pregel/__init__.py +3 -0
  325. coco_graph/pregel/_algo.py +1460 -0
  326. coco_graph/pregel/_call.py +298 -0
  327. coco_graph/pregel/_checkpoint.py +331 -0
  328. coco_graph/pregel/_config.py +0 -0
  329. coco_graph/pregel/_draw.py +294 -0
  330. coco_graph/pregel/_executor.py +223 -0
  331. coco_graph/pregel/_io.py +174 -0
  332. coco_graph/pregel/_log.py +3 -0
  333. coco_graph/pregel/_loop.py +1988 -0
  334. coco_graph/pregel/_messages.py +461 -0
  335. coco_graph/pregel/_read.py +312 -0
  336. coco_graph/pregel/_retry.py +854 -0
  337. coco_graph/pregel/_runner.py +941 -0
  338. coco_graph/pregel/_tools.py +268 -0
  339. coco_graph/pregel/_utils.py +221 -0
  340. coco_graph/pregel/_validate.py +120 -0
  341. coco_graph/pregel/_write.py +192 -0
  342. coco_graph/pregel/debug.py +302 -0
  343. coco_graph/pregel/main.py +4364 -0
  344. coco_graph/pregel/protocol.py +288 -0
  345. coco_graph/pregel/types.py +38 -0
  346. coco_graph/py.typed +0 -0
  347. coco_graph/runtime.py +350 -0
  348. coco_graph/store/base/__init__.py +1322 -0
  349. coco_graph/store/base/batch.py +371 -0
  350. coco_graph/store/base/embed.py +436 -0
  351. coco_graph/store/base/py.typed +0 -0
  352. coco_graph/store/memory/__init__.py +592 -0
  353. coco_graph/store/memory/py.typed +0 -0
  354. coco_graph/store/postgres/__init__.py +4 -0
  355. coco_graph/store/postgres/aio.py +592 -0
  356. coco_graph/store/postgres/base.py +1480 -0
  357. coco_graph/store/postgres/py.typed +0 -0
  358. coco_graph/store/sqlite/__init__.py +4 -0
  359. coco_graph/store/sqlite/aio.py +632 -0
  360. coco_graph/store/sqlite/base.py +1514 -0
  361. coco_graph/stream/__init__.py +45 -0
  362. coco_graph/stream/_convert.py +32 -0
  363. coco_graph/stream/_mux.py +523 -0
  364. coco_graph/stream/_types.py +330 -0
  365. coco_graph/stream/run_stream.py +735 -0
  366. coco_graph/stream/stream_channel.py +341 -0
  367. coco_graph/stream/transformers.py +1039 -0
  368. coco_graph/types.py +1079 -0
  369. coco_graph/typing.py +48 -0
  370. coco_graph/utils/__init__.py +1 -0
  371. coco_graph/utils/config.py +4 -0
  372. coco_graph/utils/runnable.py +3 -0
  373. coco_graph/version.py +13 -0
  374. coco_graph/warnings.py +69 -0
  375. coco_openai/__init__.py +20 -0
  376. coco_openai/_compat.py +45 -0
  377. coco_openai/_version.py +3 -0
  378. coco_openai/chat_models/__init__.py +6 -0
  379. coco_openai/chat_models/_client_utils.py +684 -0
  380. coco_openai/chat_models/_compat.py +525 -0
  381. coco_openai/chat_models/azure.py +1227 -0
  382. coco_openai/chat_models/base.py +5654 -0
  383. coco_openai/chat_models/codex.py +557 -0
  384. coco_openai/chatgpt_oauth.py +1063 -0
  385. coco_openai/data/__init__.py +1 -0
  386. coco_openai/data/_profiles.py +1655 -0
  387. coco_openai/data/profile_augmentations.toml +127 -0
  388. coco_openai/embeddings/__init__.py +6 -0
  389. coco_openai/embeddings/azure.py +240 -0
  390. coco_openai/embeddings/base.py +820 -0
  391. coco_openai/llms/__init__.py +6 -0
  392. coco_openai/llms/azure.py +249 -0
  393. coco_openai/llms/base.py +919 -0
  394. coco_openai/middleware/__init__.py +11 -0
  395. coco_openai/middleware/openai_moderation.py +484 -0
  396. coco_openai/output_parsers/__init__.py +9 -0
  397. coco_openai/output_parsers/tools.py +9 -0
  398. coco_openai/py.typed +0 -0
  399. coco_openai/tools/__init__.py +5 -0
  400. 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."""