langchain-core 0.3.0.dev4__tar.gz → 0.3.0.dev5__tar.gz

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 (171) hide show
  1. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/PKG-INFO +2 -2
  2. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/__init__.py +4 -2
  3. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/base.py +0 -4
  4. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/chat_models.py +11 -17
  5. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/tool.py +41 -7
  6. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/utils.py +11 -2
  7. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/llm_result.py +4 -1
  8. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/pydantic_v1/__init__.py +20 -0
  9. langchain_core-0.3.0.dev5/langchain_core/pydantic_v1/dataclasses.py +24 -0
  10. langchain_core-0.3.0.dev5/langchain_core/pydantic_v1/main.py +24 -0
  11. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/base.py +105 -2
  12. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/branch.py +0 -7
  13. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/configurable.py +0 -1
  14. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/graph_mermaid.py +13 -5
  15. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/history.py +36 -4
  16. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/utils.py +20 -5
  17. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/base.py +41 -8
  18. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/structured.py +3 -3
  19. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/schemas.py +17 -15
  20. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/function_calling.py +5 -2
  21. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/pyproject.toml +2 -2
  22. langchain_core-0.3.0.dev4/langchain_core/pydantic_v1/dataclasses.py +0 -4
  23. langchain_core-0.3.0.dev4/langchain_core/pydantic_v1/main.py +0 -4
  24. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/README.md +0 -0
  25. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/__init__.py +0 -0
  26. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/_api/__init__.py +0 -0
  27. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/_api/beta_decorator.py +0 -0
  28. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/_api/deprecation.py +0 -0
  29. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/_api/internal.py +0 -0
  30. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/_api/path.py +0 -0
  31. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/agents.py +0 -0
  32. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/beta/__init__.py +0 -0
  33. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/beta/runnables/__init__.py +0 -0
  34. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/beta/runnables/context.py +0 -0
  35. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/caches.py +0 -0
  36. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/__init__.py +0 -0
  37. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/base.py +0 -0
  38. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/file.py +0 -0
  39. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/manager.py +0 -0
  40. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/stdout.py +0 -0
  41. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/callbacks/streaming_stdout.py +0 -0
  42. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/chat_history.py +0 -0
  43. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/chat_loaders.py +0 -0
  44. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/chat_sessions.py +0 -0
  45. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/document_loaders/__init__.py +0 -0
  46. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/document_loaders/base.py +0 -0
  47. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/document_loaders/blob_loaders.py +0 -0
  48. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/document_loaders/langsmith.py +0 -0
  49. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/documents/__init__.py +0 -0
  50. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/documents/base.py +0 -0
  51. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/documents/compressor.py +0 -0
  52. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/documents/transformers.py +0 -0
  53. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/embeddings/__init__.py +0 -0
  54. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/embeddings/embeddings.py +0 -0
  55. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/embeddings/fake.py +0 -0
  56. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/env.py +0 -0
  57. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/example_selectors/__init__.py +0 -0
  58. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/example_selectors/base.py +0 -0
  59. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/example_selectors/length_based.py +0 -0
  60. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/example_selectors/semantic_similarity.py +0 -0
  61. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/exceptions.py +0 -0
  62. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/globals.py +0 -0
  63. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/graph_vectorstores/__init__.py +0 -0
  64. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/graph_vectorstores/base.py +0 -0
  65. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/graph_vectorstores/links.py +0 -0
  66. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/indexing/__init__.py +0 -0
  67. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/indexing/api.py +0 -0
  68. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/indexing/base.py +0 -0
  69. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/indexing/in_memory.py +0 -0
  70. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/fake.py +0 -0
  71. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/fake_chat_models.py +0 -0
  72. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/language_models/llms.py +0 -0
  73. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/load/__init__.py +0 -0
  74. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/load/dump.py +0 -0
  75. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/load/load.py +0 -0
  76. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/load/mapping.py +0 -0
  77. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/load/serializable.py +0 -0
  78. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/memory.py +0 -0
  79. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/__init__.py +0 -0
  80. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/ai.py +0 -0
  81. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/base.py +0 -0
  82. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/chat.py +0 -0
  83. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/function.py +0 -0
  84. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/human.py +0 -0
  85. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/modifier.py +0 -0
  86. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/messages/system.py +0 -0
  87. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/__init__.py +0 -0
  88. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/base.py +0 -0
  89. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/format_instructions.py +0 -0
  90. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/json.py +0 -0
  91. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/list.py +0 -0
  92. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/openai_functions.py +0 -0
  93. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/openai_tools.py +0 -0
  94. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/pydantic.py +0 -0
  95. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/string.py +0 -0
  96. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/transform.py +0 -0
  97. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/output_parsers/xml.py +0 -0
  98. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/__init__.py +0 -0
  99. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/chat_generation.py +0 -0
  100. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/chat_result.py +0 -0
  101. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/generation.py +0 -0
  102. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/outputs/run_info.py +0 -0
  103. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompt_values.py +0 -0
  104. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/__init__.py +0 -0
  105. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/base.py +0 -0
  106. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/chat.py +0 -0
  107. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/few_shot.py +0 -0
  108. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/few_shot_with_templates.py +0 -0
  109. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/image.py +0 -0
  110. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/loading.py +0 -0
  111. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/pipeline.py +0 -0
  112. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/prompt.py +0 -0
  113. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/string.py +0 -0
  114. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/prompts/structured.py +0 -0
  115. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/py.typed +0 -0
  116. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/rate_limiters.py +0 -0
  117. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/retrievers.py +0 -0
  118. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/__init__.py +0 -0
  119. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/config.py +0 -0
  120. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/fallbacks.py +0 -0
  121. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/graph.py +0 -0
  122. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/graph_ascii.py +0 -0
  123. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/graph_png.py +0 -0
  124. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/learnable.py +0 -0
  125. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/passthrough.py +0 -0
  126. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/retry.py +0 -0
  127. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/router.py +0 -0
  128. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/runnables/schema.py +0 -0
  129. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/stores.py +0 -0
  130. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/structured_query.py +0 -0
  131. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/sys_info.py +0 -0
  132. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/__init__.py +0 -0
  133. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/convert.py +0 -0
  134. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/render.py +0 -0
  135. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/retriever.py +0 -0
  136. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tools/simple.py +0 -0
  137. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/__init__.py +0 -0
  138. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/_streaming.py +0 -0
  139. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/base.py +0 -0
  140. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/context.py +0 -0
  141. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/core.py +0 -0
  142. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/evaluation.py +0 -0
  143. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/event_stream.py +0 -0
  144. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/langchain.py +0 -0
  145. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/langchain_v1.py +0 -0
  146. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/log_stream.py +0 -0
  147. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/memory_stream.py +0 -0
  148. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/root_listeners.py +0 -0
  149. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/run_collector.py +0 -0
  150. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/tracers/stdout.py +0 -0
  151. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/__init__.py +0 -0
  152. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/_merge.py +0 -0
  153. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/aiter.py +0 -0
  154. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/env.py +0 -0
  155. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/formatting.py +0 -0
  156. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/html.py +0 -0
  157. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/image.py +0 -0
  158. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/input.py +0 -0
  159. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/interactive_env.py +0 -0
  160. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/iter.py +0 -0
  161. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/json.py +0 -0
  162. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/json_schema.py +0 -0
  163. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/loading.py +0 -0
  164. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/mustache.py +0 -0
  165. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/pydantic.py +0 -0
  166. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/strings.py +0 -0
  167. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/utils/utils.py +0 -0
  168. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/vectorstores/__init__.py +0 -0
  169. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/vectorstores/base.py +0 -0
  170. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/vectorstores/in_memory.py +0 -0
  171. {langchain_core-0.3.0.dev4 → langchain_core-0.3.0.dev5}/langchain_core/vectorstores/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-core
3
- Version: 0.3.0.dev4
3
+ Version: 0.3.0.dev5
4
4
  Summary: Building applications with LLMs through composability
5
5
  Home-page: https://github.com/langchain-ai/langchain
6
6
  License: MIT
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Requires-Dist: PyYAML (>=5.3)
15
15
  Requires-Dist: jsonpatch (>=1.33,<2.0)
16
- Requires-Dist: langsmith (>=0.1.112,<0.2.0)
16
+ Requires-Dist: langsmith (>=0.1.117,<0.2.0)
17
17
  Requires-Dist: packaging (>=23.2,<25)
18
18
  Requires-Dist: pydantic (>=2.7.4,<3.0.0)
19
19
  Requires-Dist: tenacity (>=8.1.0,<9.0.0,!=8.4.0)
@@ -4,7 +4,7 @@ text prompts.
4
4
  LangChain has two main classes to work with language models: **Chat Models**
5
5
  and "old-fashioned" **LLMs**.
6
6
 
7
- ## Chat Models
7
+ **Chat Models**
8
8
 
9
9
  Language models that use a sequence of messages as inputs and return chat messages
10
10
  as outputs (as opposed to using plain text). These are traditionally newer models (
@@ -21,7 +21,7 @@ the following guide for more information on how to implement a custom Chat Model
21
21
 
22
22
  https://python.langchain.com/v0.2/docs/how_to/custom_chat_model/
23
23
 
24
- ## LLMs
24
+ **LLMs**
25
25
 
26
26
  Language models that takes a string as input and returns a string.
27
27
  These are traditionally older models (newer models generally are Chat Models, see below).
@@ -35,6 +35,8 @@ To implement a custom LLM, inherit from `BaseLLM` or `LLM`.
35
35
  Please see the following guide for more information on how to implement a custom LLM:
36
36
 
37
37
  https://python.langchain.com/v0.2/docs/how_to/custom_llm/
38
+
39
+
38
40
  """ # noqa: E501
39
41
 
40
42
  from langchain_core.language_models.base import (
@@ -113,10 +113,6 @@ class BaseLanguageModel(
113
113
 
114
114
  Caching is not currently supported for streaming methods of models.
115
115
  """
116
- # Repr = False is consistent with pydantic 1 if verbose = False
117
- # We can relax this for pydantic 2?
118
- # TODO(0.3): Resolve repr for verbose
119
- # Modified just to get unit tests to pass.
120
116
  verbose: bool = Field(default_factory=_get_verbosity, exclude=True, repr=False)
121
117
  """Whether to print out response text."""
122
118
  callbacks: Callbacks = Field(default=None, exclude=True)
@@ -195,20 +195,14 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC):
195
195
 
196
196
  """ # noqa: E501
197
197
 
198
- # TODO(0.3): Figure out how to re-apply deprecated decorator
199
- # callback_manager: Optional[BaseCallbackManager] = deprecated(
200
- # name="callback_manager", since="0.1.7", removal="1.0", alternative="callbacks"
201
- # )(
202
- # Field(
203
- # default=None,
204
- # exclude=True,
205
- # description="Callback manager to add to the run trace.",
206
- # )
207
- # )
208
- callback_manager: Optional[BaseCallbackManager] = Field(
209
- default=None,
210
- exclude=True,
211
- description="Callback manager to add to the run trace.",
198
+ callback_manager: Optional[BaseCallbackManager] = deprecated(
199
+ name="callback_manager", since="0.1.7", removal="1.0", alternative="callbacks"
200
+ )(
201
+ Field(
202
+ default=None,
203
+ exclude=True,
204
+ description="Callback manager to add to the run trace.",
205
+ )
212
206
  )
213
207
 
214
208
  rate_limiter: Optional[BaseRateLimiter] = Field(default=None, exclude=True)
@@ -1180,7 +1174,7 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC):
1180
1174
  Example: Pydantic schema (include_raw=False):
1181
1175
  .. code-block:: python
1182
1176
 
1183
- from langchain_core.pydantic_v1 import BaseModel
1177
+ from pydantic import BaseModel
1184
1178
 
1185
1179
  class AnswerWithJustification(BaseModel):
1186
1180
  '''An answer to the user question along with justification for the answer.'''
@@ -1200,7 +1194,7 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC):
1200
1194
  Example: Pydantic schema (include_raw=True):
1201
1195
  .. code-block:: python
1202
1196
 
1203
- from langchain_core.pydantic_v1 import BaseModel
1197
+ from pydantic import BaseModel
1204
1198
 
1205
1199
  class AnswerWithJustification(BaseModel):
1206
1200
  '''An answer to the user question along with justification for the answer.'''
@@ -1220,7 +1214,7 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC):
1220
1214
  Example: Dict schema (include_raw=False):
1221
1215
  .. code-block:: python
1222
1216
 
1223
- from langchain_core.pydantic_v1 import BaseModel
1217
+ from pydantic import BaseModel
1224
1218
  from langchain_core.utils.function_calling import convert_to_openai_tool
1225
1219
 
1226
1220
  class AnswerWithJustification(BaseModel):
@@ -1,7 +1,8 @@
1
1
  import json
2
2
  from typing import Any, Dict, List, Literal, Optional, Tuple, Union
3
+ from uuid import UUID
3
4
 
4
- from pydantic import Field
5
+ from pydantic import Field, model_validator
5
6
  from typing_extensions import NotRequired, TypedDict
6
7
 
7
8
  from langchain_core.messages.base import BaseMessage, BaseMessageChunk, merge_content
@@ -82,15 +83,48 @@ class ToolMessage(BaseMessage):
82
83
  Default is ["langchain", "schema", "messages"]."""
83
84
  return ["langchain", "schema", "messages"]
84
85
 
86
+ @model_validator(mode="before")
87
+ @classmethod
88
+ def coerce_args(cls, values: dict) -> dict:
89
+ content = values["content"]
90
+ if isinstance(content, tuple):
91
+ content = list(content)
92
+
93
+ if not isinstance(content, (str, list)):
94
+ try:
95
+ values["content"] = str(content)
96
+ except ValueError as e:
97
+ raise ValueError(
98
+ "ToolMessage content should be a string or a list of string/dicts. "
99
+ f"Received:\n\n{content=}\n\n which could not be coerced into a "
100
+ "string."
101
+ ) from e
102
+ elif isinstance(content, list):
103
+ values["content"] = []
104
+ for i, x in enumerate(content):
105
+ if not isinstance(x, (str, dict)):
106
+ try:
107
+ values["content"].append(str(x))
108
+ except ValueError as e:
109
+ raise ValueError(
110
+ "ToolMessage content should be a string or a list of "
111
+ "string/dicts. Received a list but "
112
+ f"element ToolMessage.content[{i}] is not a dict and could "
113
+ f"not be coerced to a string.:\n\n{x}"
114
+ ) from e
115
+ else:
116
+ values["content"].append(x)
117
+ else:
118
+ pass
119
+
120
+ tool_call_id = values["tool_call_id"]
121
+ if isinstance(tool_call_id, UUID):
122
+ values["tool_call_id"] = str(tool_call_id)
123
+ return values
124
+
85
125
  def __init__(
86
126
  self, content: Union[str, List[Union[str, Dict]]], **kwargs: Any
87
127
  ) -> None:
88
- """Pass in content as positional arg.
89
-
90
- Args:
91
- content: The string contents of the message.
92
- kwargs: Additional fields to pass to the message
93
- """
94
128
  super().__init__(content=content, **kwargs)
95
129
 
96
130
 
@@ -50,7 +50,16 @@ if TYPE_CHECKING:
50
50
 
51
51
 
52
52
  def _get_type(v: Any) -> str:
53
- return v.type
53
+ """Get the type associated with the object for serialization purposes."""
54
+ if isinstance(v, dict) and "type" in v:
55
+ return v["type"]
56
+ elif hasattr(v, "type"):
57
+ return v.type
58
+ else:
59
+ raise TypeError(
60
+ f"Expected either a dictionary with a 'type' key or an object "
61
+ f"with a 'type' attribute. Instead got type {type(v)}."
62
+ )
54
63
 
55
64
 
56
65
  AnyMessage = Annotated[
@@ -263,7 +272,7 @@ def _create_message_from_message_type(
263
272
  message = RemoveMessage(**kwargs)
264
273
  else:
265
274
  raise ValueError(
266
- f"Unexpected message type: {message_type}. Use one of 'human',"
275
+ f"Unexpected message type: '{message_type}'. Use one of 'human',"
267
276
  f" 'user', 'ai', 'assistant', 'function', 'tool', or 'system'."
268
277
  )
269
278
  return message
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from copy import deepcopy
4
- from typing import List, Optional, Union
4
+ from typing import List, Literal, Optional, Union
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
@@ -48,6 +48,9 @@ class LLMResult(BaseModel):
48
48
  run: Optional[List[RunInfo]] = None
49
49
  """List of metadata info for model call for each input."""
50
50
 
51
+ type: Literal["LLMResult"] = "LLMResult" # type: ignore[assignment]
52
+ """Type is used exclusively for serialization purposes."""
53
+
51
54
  def flatten(self) -> List[LLMResult]:
52
55
  """Flatten generations into a single list.
53
56
 
@@ -1,5 +1,7 @@
1
1
  from importlib import metadata
2
2
 
3
+ from langchain_core._api.deprecation import warn_deprecated
4
+
3
5
  ## Create namespaces for pydantic v1 and v2.
4
6
  # This code must stay at the top of the file before other modules may
5
7
  # attempt to import pydantic since it adds pydantic_v1 and pydantic_v2 to sys.modules.
@@ -21,3 +23,21 @@ try:
21
23
  _PYDANTIC_MAJOR_VERSION: int = int(metadata.version("pydantic").split(".")[0])
22
24
  except metadata.PackageNotFoundError:
23
25
  _PYDANTIC_MAJOR_VERSION = 0
26
+
27
+ warn_deprecated(
28
+ "0.3.0",
29
+ removal="1.0.0",
30
+ alternative="pydantic.v1 or pydantic",
31
+ message=(
32
+ "As of langchain-core 0.3.0, LangChain uses pydantic v2 internally. "
33
+ "The langchain_core.pydantic_v1 module was a "
34
+ "compatibility shim for pydantic v1, and should no longer be used. "
35
+ "Please update the code to import from Pydantic directly.\n\n"
36
+ "For example, replace imports like: "
37
+ "`from langchain_core.pydantic_v1 import BaseModel`\n"
38
+ "with: `from pydantic import BaseModel`\n"
39
+ "or the v1 compatibility namespace if you are working in a code base "
40
+ "that has not been fully upgraded to pydantic 2 yet. "
41
+ "\tfrom pydantic.v1 import BaseModel\n"
42
+ ),
43
+ )
@@ -0,0 +1,24 @@
1
+ from langchain_core._api import warn_deprecated
2
+
3
+ try:
4
+ from pydantic.v1.dataclasses import * # noqa: F403
5
+ except ImportError:
6
+ from pydantic.dataclasses import * # type: ignore # noqa: F403
7
+
8
+ warn_deprecated(
9
+ "0.3.0",
10
+ removal="1.0.0",
11
+ alternative="pydantic.v1 or pydantic",
12
+ message=(
13
+ "As of langchain-core 0.3.0, LangChain uses pydantic v2 internally. "
14
+ "The langchain_core.pydantic_v1 module was a "
15
+ "compatibility shim for pydantic v1, and should no longer be used. "
16
+ "Please update the code to import from Pydantic directly.\n\n"
17
+ "For example, replace imports like: "
18
+ "`from langchain_core.pydantic_v1 import BaseModel`\n"
19
+ "with: `from pydantic import BaseModel`\n"
20
+ "or the v1 compatibility namespace if you are working in a code base "
21
+ "that has not been fully upgraded to pydantic 2 yet. "
22
+ "\tfrom pydantic.v1 import BaseModel\n"
23
+ ),
24
+ )
@@ -0,0 +1,24 @@
1
+ from langchain_core._api import warn_deprecated
2
+
3
+ try:
4
+ from pydantic.v1.main import * # noqa: F403
5
+ except ImportError:
6
+ from pydantic.main import * # type: ignore # noqa: F403
7
+
8
+ warn_deprecated(
9
+ "0.3.0",
10
+ removal="1.0.0",
11
+ alternative="pydantic.v1 or pydantic",
12
+ message=(
13
+ "As of langchain-core 0.3.0, LangChain uses pydantic v2 internally. "
14
+ "The langchain_core.pydantic_v1 module was a "
15
+ "compatibility shim for pydantic v1, and should no longer be used. "
16
+ "Please update the code to import from Pydantic directly.\n\n"
17
+ "For example, replace imports like: "
18
+ "`from langchain_core.pydantic_v1 import BaseModel`\n"
19
+ "with: `from pydantic import BaseModel`\n"
20
+ "or the v1 compatibility namespace if you are working in a code base "
21
+ "that has not been fully upgraded to pydantic 2 yet. "
22
+ "\tfrom pydantic.v1 import BaseModel\n"
23
+ ),
24
+ )
@@ -348,6 +348,14 @@ class Runnable(Generic[Input, Output], ABC):
348
348
  return create_model(
349
349
  self.get_name("Input"),
350
350
  __root__=root_type,
351
+ # create model needs access to appropriate type annotations to be
352
+ # able to construct the pydantic model.
353
+ # When we create the model, we pass information about the namespace
354
+ # where the model is being created, so the type annotations can
355
+ # be resolved correctly as well.
356
+ # self.__class__.__module__ handles the case when the Runnable is
357
+ # being sub-classed in a different module.
358
+ __module_name=self.__class__.__module__,
351
359
  )
352
360
 
353
361
  def get_input_jsonschema(
@@ -408,6 +416,14 @@ class Runnable(Generic[Input, Output], ABC):
408
416
  return create_model(
409
417
  self.get_name("Output"),
410
418
  __root__=root_type,
419
+ # create model needs access to appropriate type annotations to be
420
+ # able to construct the pydantic model.
421
+ # When we create the model, we pass information about the namespace
422
+ # where the model is being created, so the type annotations can
423
+ # be resolved correctly as well.
424
+ # self.__class__.__module__ handles the case when the Runnable is
425
+ # being sub-classed in a different module.
426
+ __module_name=self.__class__.__module__,
411
427
  )
412
428
 
413
429
  def get_output_jsonschema(
@@ -1094,7 +1110,6 @@ class Runnable(Generic[Input, Output], ABC):
1094
1110
  ):
1095
1111
  yield item
1096
1112
 
1097
- @beta_decorator.beta(message="This API is in beta and may change in the future.")
1098
1113
  async def astream_events(
1099
1114
  self,
1100
1115
  input: Any,
@@ -2364,7 +2379,7 @@ class Runnable(Generic[Input, Output], ABC):
2364
2379
  .. code-block:: python
2365
2380
 
2366
2381
  from typing import Any, Dict, List
2367
- from langchain_core.pydantic_v1 import BaseModel, Field
2382
+ from pydantic import BaseModel, Field
2368
2383
  from langchain_core.runnables import RunnableLambda
2369
2384
 
2370
2385
  def f(x: Dict[str, Any]) -> str:
@@ -4047,6 +4062,29 @@ class RunnableGenerator(Runnable[Input, Output]):
4047
4062
  except ValueError:
4048
4063
  return Any
4049
4064
 
4065
+ def get_input_schema(
4066
+ self, config: Optional[RunnableConfig] = None
4067
+ ) -> Type[BaseModel]:
4068
+ # Override the default implementation.
4069
+ # For a runnable generator, we need to bring to provide the
4070
+ # module of the underlying function when creating the model.
4071
+ root_type = self.InputType
4072
+
4073
+ func = getattr(self, "_transform", None) or self._atransform
4074
+ module = getattr(func, "__module__", None)
4075
+
4076
+ if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
4077
+ return root_type
4078
+
4079
+ return create_model(
4080
+ self.get_name("Input"),
4081
+ __root__=root_type,
4082
+ # To create the schema, we need to provide the module
4083
+ # where the underlying function is defined.
4084
+ # This allows pydantic to resolve type annotations appropriately.
4085
+ __module_name=module,
4086
+ )
4087
+
4050
4088
  @property
4051
4089
  def OutputType(self) -> Any:
4052
4090
  func = getattr(self, "_transform", None) or self._atransform
@@ -4060,6 +4098,28 @@ class RunnableGenerator(Runnable[Input, Output]):
4060
4098
  except ValueError:
4061
4099
  return Any
4062
4100
 
4101
+ def get_output_schema(
4102
+ self, config: Optional[RunnableConfig] = None
4103
+ ) -> Type[BaseModel]:
4104
+ # Override the default implementation.
4105
+ # For a runnable generator, we need to bring to provide the
4106
+ # module of the underlying function when creating the model.
4107
+ root_type = self.OutputType
4108
+ func = getattr(self, "_transform", None) or self._atransform
4109
+ module = getattr(func, "__module__", None)
4110
+
4111
+ if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
4112
+ return root_type
4113
+
4114
+ return create_model(
4115
+ self.get_name("Output"),
4116
+ __root__=root_type,
4117
+ # To create the schema, we need to provide the module
4118
+ # where the underlying function is defined.
4119
+ # This allows pydantic to resolve type annotations appropriately.
4120
+ __module_name=module,
4121
+ )
4122
+
4063
4123
  def __eq__(self, other: Any) -> bool:
4064
4124
  if isinstance(other, RunnableGenerator):
4065
4125
  if hasattr(self, "_transform") and hasattr(other, "_transform"):
@@ -4308,9 +4368,14 @@ class RunnableLambda(Runnable[Input, Output]):
4308
4368
  # It's a dict, lol
4309
4369
  return create_model(self.get_name("Input"), **fields)
4310
4370
  else:
4371
+ module = getattr(func, "__module__", None)
4311
4372
  return create_model(
4312
4373
  self.get_name("Input"),
4313
4374
  __root__=List[Any],
4375
+ # To create the schema, we need to provide the module
4376
+ # where the underlying function is defined.
4377
+ # This allows pydantic to resolve type annotations appropriately.
4378
+ __module_name=module,
4314
4379
  )
4315
4380
 
4316
4381
  if self.InputType != Any:
@@ -4347,6 +4412,28 @@ class RunnableLambda(Runnable[Input, Output]):
4347
4412
  except ValueError:
4348
4413
  return Any
4349
4414
 
4415
+ def get_output_schema(
4416
+ self, config: Optional[RunnableConfig] = None
4417
+ ) -> Type[BaseModel]:
4418
+ # Override the default implementation.
4419
+ # For a runnable lambda, we need to bring to provide the
4420
+ # module of the underlying function when creating the model.
4421
+ root_type = self.OutputType
4422
+ func = getattr(self, "func", None) or self.afunc
4423
+ module = getattr(func, "__module__", None)
4424
+
4425
+ if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
4426
+ return root_type
4427
+
4428
+ return create_model(
4429
+ self.get_name("Output"),
4430
+ __root__=root_type,
4431
+ # To create the schema, we need to provide the module
4432
+ # where the underlying function is defined.
4433
+ # This allows pydantic to resolve type annotations appropriately.
4434
+ __module_name=module,
4435
+ )
4436
+
4350
4437
  @property
4351
4438
  def deps(self) -> List[Runnable]:
4352
4439
  """The dependencies of this Runnable.
@@ -4864,6 +4951,14 @@ class RunnableEachBase(RunnableSerializable[List[Input], List[Output]]):
4864
4951
  List[self.bound.get_input_schema(config)], # type: ignore
4865
4952
  None,
4866
4953
  ),
4954
+ # create model needs access to appropriate type annotations to be
4955
+ # able to construct the pydantic model.
4956
+ # When we create the model, we pass information about the namespace
4957
+ # where the model is being created, so the type annotations can
4958
+ # be resolved correctly as well.
4959
+ # self.__class__.__module__ handles the case when the Runnable is
4960
+ # being sub-classed in a different module.
4961
+ __module_name=self.__class__.__module__,
4867
4962
  )
4868
4963
 
4869
4964
  @property
@@ -4877,6 +4972,14 @@ class RunnableEachBase(RunnableSerializable[List[Input], List[Output]]):
4877
4972
  return create_model(
4878
4973
  self.get_name("Output"),
4879
4974
  __root__=List[schema], # type: ignore[valid-type]
4975
+ # create model needs access to appropriate type annotations to be
4976
+ # able to construct the pydantic model.
4977
+ # When we create the model, we pass information about the namespace
4978
+ # where the model is being created, so the type annotations can
4979
+ # be resolved correctly as well.
4980
+ # self.__class__.__module__ handles the case when the Runnable is
4981
+ # being sub-classed in a different module.
4982
+ __module_name=self.__class__.__module__,
4880
4983
  )
4881
4984
 
4882
4985
  @property
@@ -138,13 +138,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
138
138
  super().__init__(
139
139
  branches=_branches,
140
140
  default=default_,
141
- # Hard-coding a name here because RunnableBranch is a generic
142
- # and with pydantic 2, the class name with pydantic will capture
143
- # include the parameterized type, which is not what we want.
144
- # e.g., we'd get RunnableBranch[Input, Output] instead of RunnableBranch
145
- # for the name. This information is already captured in the
146
- # input and output types.
147
- name="RunnableBranch",
148
141
  ) # type: ignore[call-arg]
149
142
 
150
143
  model_config = ConfigDict(
@@ -376,7 +376,6 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]):
376
376
  Returns:
377
377
  List[ConfigurableFieldSpec]: The configuration specs.
378
378
  """
379
- # TODO(0.3): This change removes field_info which isn't needed in pydantic 2
380
379
  config_specs = []
381
380
 
382
381
  for field_name, spec in self.fields.items():
@@ -11,6 +11,8 @@ from langchain_core.runnables.graph import (
11
11
  NodeStyles,
12
12
  )
13
13
 
14
+ MARKDOWN_SPECIAL_CHARS = "*_`"
15
+
14
16
 
15
17
  def draw_mermaid(
16
18
  nodes: Dict[str, Node],
@@ -58,13 +60,19 @@ def draw_mermaid(
58
60
  default_class_label = "default"
59
61
  format_dict = {default_class_label: "{0}({1})"}
60
62
  if first_node is not None:
61
- format_dict[first_node] = "{0}([{0}]):::first"
63
+ format_dict[first_node] = "{0}([{1}]):::first"
62
64
  if last_node is not None:
63
- format_dict[last_node] = "{0}([{0}]):::last"
65
+ format_dict[last_node] = "{0}([{1}]):::last"
64
66
 
65
67
  # Add nodes to the graph
66
68
  for key, node in nodes.items():
67
- label = node.name.split(":")[-1]
69
+ node_name = node.name.split(":")[-1]
70
+ label = (
71
+ f"<p>{node_name}</p>"
72
+ if node_name.startswith(tuple(MARKDOWN_SPECIAL_CHARS))
73
+ and node_name.endswith(tuple(MARKDOWN_SPECIAL_CHARS))
74
+ else node_name
75
+ )
68
76
  if node.metadata:
69
77
  label = (
70
78
  f"{label}<hr/><small><em>"
@@ -119,9 +127,9 @@ def draw_mermaid(
119
127
  for i in range(0, len(words), wrap_label_n_words)
120
128
  )
121
129
  if edge.conditional:
122
- edge_label = f" -. &nbsp{edge_data}&nbsp .-> "
130
+ edge_label = f" -. &nbsp;{edge_data}&nbsp; .-> "
123
131
  else:
124
- edge_label = f" -- &nbsp{edge_data}&nbsp --> "
132
+ edge_label = f" -- &nbsp;{edge_data}&nbsp; --> "
125
133
  else:
126
134
  if edge.conditional:
127
135
  edge_label = " -.-> "
@@ -21,6 +21,7 @@ from langchain_core.runnables.base import Runnable, RunnableBindingBase, Runnabl
21
21
  from langchain_core.runnables.passthrough import RunnablePassthrough
22
22
  from langchain_core.runnables.utils import (
23
23
  ConfigurableFieldSpec,
24
+ Output,
24
25
  create_model,
25
26
  get_unique_config_specs,
26
27
  )
@@ -97,7 +98,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
97
98
  from langchain_core.documents import Document
98
99
  from langchain_core.messages import BaseMessage, AIMessage
99
100
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
100
- from langchain_core.pydantic_v1 import BaseModel, Field
101
+ from pydantic import BaseModel, Field
101
102
  from langchain_core.runnables import (
102
103
  RunnableLambda,
103
104
  ConfigurableFieldSpec,
@@ -362,6 +363,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
362
363
  history_factory_config=_config_specs,
363
364
  **kwargs,
364
365
  )
366
+ self._history_chain = history_chain
365
367
 
366
368
  @property
367
369
  def config_specs(self) -> List[ConfigurableFieldSpec]:
@@ -373,9 +375,6 @@ class RunnableWithMessageHistory(RunnableBindingBase):
373
375
  def get_input_schema(
374
376
  self, config: Optional[RunnableConfig] = None
375
377
  ) -> Type[BaseModel]:
376
- # TODO(0.3): Verify that this change was correct
377
- # Not enough tests and unclear on why the previous implementation was
378
- # necessary.
379
378
  from langchain_core.messages import BaseMessage
380
379
 
381
380
  fields: Dict = {}
@@ -393,6 +392,39 @@ class RunnableWithMessageHistory(RunnableBindingBase):
393
392
  **fields,
394
393
  )
395
394
 
395
+ @property
396
+ def OutputType(self) -> Type[Output]:
397
+ output_type = self._history_chain.OutputType
398
+ return output_type
399
+
400
+ def get_output_schema(
401
+ self, config: Optional[RunnableConfig] = None
402
+ ) -> Type[BaseModel]:
403
+ """Get a pydantic model that can be used to validate output to the Runnable.
404
+
405
+ Runnables that leverage the configurable_fields and configurable_alternatives
406
+ methods will have a dynamic output schema that depends on which
407
+ configuration the Runnable is invoked with.
408
+
409
+ This method allows to get an output schema for a specific configuration.
410
+
411
+ Args:
412
+ config: A config to use when generating the schema.
413
+
414
+ Returns:
415
+ A pydantic model that can be used to validate output.
416
+ """
417
+ root_type = self.OutputType
418
+
419
+ if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
420
+ return root_type
421
+
422
+ return create_model(
423
+ "RunnableWithChatHistoryOutput",
424
+ __root__=root_type,
425
+ __module_name=self.__class__.__module__,
426
+ )
427
+
396
428
  def _is_not_async(self, *args: Sequence[Any], **kwargs: Dict[str, Any]) -> bool:
397
429
  return False
398
430