langroid 0.49.0__tar.gz → 0.50.0__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 (135) hide show
  1. {langroid-0.49.0 → langroid-0.50.0}/PKG-INFO +2 -1
  2. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/doc_chat_agent.py +1 -1
  3. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/openai_gpt.py +56 -7
  4. {langroid-0.49.0 → langroid-0.50.0}/langroid/mytypes.py +28 -1
  5. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/document_parser.py +0 -3
  6. langroid-0.50.0/langroid/parsing/md_parser.py +574 -0
  7. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/parser.py +34 -10
  8. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/url_loader.py +20 -3
  9. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/output/citations.py +2 -2
  10. {langroid-0.49.0 → langroid-0.50.0}/pyproject.toml +3 -1
  11. {langroid-0.49.0 → langroid-0.50.0}/.gitignore +0 -0
  12. {langroid-0.49.0 → langroid-0.50.0}/LICENSE +0 -0
  13. {langroid-0.49.0 → langroid-0.50.0}/README.md +0 -0
  14. {langroid-0.49.0 → langroid-0.50.0}/langroid/__init__.py +0 -0
  15. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/__init__.py +0 -0
  16. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/base.py +0 -0
  17. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/batch.py +0 -0
  18. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/callbacks/__init__.py +0 -0
  19. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/callbacks/chainlit.py +0 -0
  20. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/chat_agent.py +0 -0
  21. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/chat_document.py +0 -0
  22. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/openai_assistant.py +0 -0
  23. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/__init__.py +0 -0
  24. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/arangodb/__init__.py +0 -0
  25. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/arangodb/arangodb_agent.py +0 -0
  26. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/arangodb/system_messages.py +0 -0
  27. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/arangodb/tools.py +0 -0
  28. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/arangodb/utils.py +0 -0
  29. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
  30. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_rag/__init__.py +0 -0
  31. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
  32. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
  33. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
  34. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/lance_tools.py +0 -0
  35. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/neo4j/__init__.py +0 -0
  36. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
  37. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
  38. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/neo4j/system_messages.py +0 -0
  39. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/neo4j/tools.py +0 -0
  40. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/relevance_extractor_agent.py +0 -0
  41. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/retriever_agent.py +0 -0
  42. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/__init__.py +0 -0
  43. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
  44. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/utils/__init__.py +0 -0
  45. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
  46. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
  47. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/utils/system_message.py +0 -0
  48. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/sql/utils/tools.py +0 -0
  49. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/special/table_chat_agent.py +0 -0
  50. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/task.py +0 -0
  51. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tool_message.py +0 -0
  52. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/__init__.py +0 -0
  53. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
  54. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/exa_search_tool.py +0 -0
  55. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/file_tools.py +0 -0
  56. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/google_search_tool.py +0 -0
  57. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/metaphor_search_tool.py +0 -0
  58. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/orchestration.py +0 -0
  59. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/recipient_tool.py +0 -0
  60. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/retrieval_tool.py +0 -0
  61. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/rewind_tool.py +0 -0
  62. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/segment_extract_tool.py +0 -0
  63. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/tools/tavily_search_tool.py +0 -0
  64. {langroid-0.49.0 → langroid-0.50.0}/langroid/agent/xml_tool_message.py +0 -0
  65. {langroid-0.49.0 → langroid-0.50.0}/langroid/cachedb/__init__.py +0 -0
  66. {langroid-0.49.0 → langroid-0.50.0}/langroid/cachedb/base.py +0 -0
  67. {langroid-0.49.0 → langroid-0.50.0}/langroid/cachedb/momento_cachedb.py +0 -0
  68. {langroid-0.49.0 → langroid-0.50.0}/langroid/cachedb/redis_cachedb.py +0 -0
  69. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/__init__.py +0 -0
  70. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/base.py +0 -0
  71. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/models.py +0 -0
  72. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/protoc/__init__.py +0 -0
  73. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/protoc/embeddings.proto +0 -0
  74. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
  75. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
  76. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
  77. {langroid-0.49.0 → langroid-0.50.0}/langroid/embedding_models/remote_embeds.py +0 -0
  78. {langroid-0.49.0 → langroid-0.50.0}/langroid/exceptions.py +0 -0
  79. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/__init__.py +0 -0
  80. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/azure_openai.py +0 -0
  81. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/base.py +0 -0
  82. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/config.py +0 -0
  83. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/mock_lm.py +0 -0
  84. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/model_info.py +0 -0
  85. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/prompt_formatter/__init__.py +0 -0
  86. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/prompt_formatter/base.py +0 -0
  87. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
  88. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
  89. {langroid-0.49.0 → langroid-0.50.0}/langroid/language_models/utils.py +0 -0
  90. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/__init__.py +0 -0
  91. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/agent_chats.py +0 -0
  92. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/code_parser.py +0 -0
  93. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/para_sentence_split.py +0 -0
  94. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/parse_json.py +0 -0
  95. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/pdf_utils.py +0 -0
  96. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/repo_loader.py +0 -0
  97. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/routing.py +0 -0
  98. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/search.py +0 -0
  99. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/spider.py +0 -0
  100. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/table_loader.py +0 -0
  101. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/urls.py +0 -0
  102. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/utils.py +0 -0
  103. {langroid-0.49.0 → langroid-0.50.0}/langroid/parsing/web_search.py +0 -0
  104. {langroid-0.49.0 → langroid-0.50.0}/langroid/prompts/__init__.py +0 -0
  105. {langroid-0.49.0 → langroid-0.50.0}/langroid/prompts/dialog.py +0 -0
  106. {langroid-0.49.0 → langroid-0.50.0}/langroid/prompts/prompts_config.py +0 -0
  107. {langroid-0.49.0 → langroid-0.50.0}/langroid/prompts/templates.py +0 -0
  108. {langroid-0.49.0 → langroid-0.50.0}/langroid/py.typed +0 -0
  109. {langroid-0.49.0 → langroid-0.50.0}/langroid/pydantic_v1/__init__.py +0 -0
  110. {langroid-0.49.0 → langroid-0.50.0}/langroid/pydantic_v1/main.py +0 -0
  111. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/__init__.py +0 -0
  112. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/algorithms/__init__.py +0 -0
  113. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/algorithms/graph.py +0 -0
  114. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/configuration.py +0 -0
  115. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/constants.py +0 -0
  116. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/git_utils.py +0 -0
  117. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/globals.py +0 -0
  118. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/logging.py +0 -0
  119. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/object_registry.py +0 -0
  120. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/output/__init__.py +0 -0
  121. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/output/printing.py +0 -0
  122. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/output/status.py +0 -0
  123. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/pandas_utils.py +0 -0
  124. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/pydantic_utils.py +0 -0
  125. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/system.py +0 -0
  126. {langroid-0.49.0 → langroid-0.50.0}/langroid/utils/types.py +0 -0
  127. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/__init__.py +0 -0
  128. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/base.py +0 -0
  129. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/chromadb.py +0 -0
  130. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/lancedb.py +0 -0
  131. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/meilisearch.py +0 -0
  132. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/pineconedb.py +0 -0
  133. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/postgres.py +0 -0
  134. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/qdrantdb.py +0 -0
  135. {langroid-0.49.0 → langroid-0.50.0}/langroid/vector_store/weaviatedb.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langroid
3
- Version: 0.49.0
3
+ Version: 0.50.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  Author-email: Prasad Chalasani <pchalasani@gmail.com>
6
6
  License: MIT
@@ -27,6 +27,7 @@ Requires-Dist: halo<1.0.0,>=0.0.31
27
27
  Requires-Dist: jinja2<4.0.0,>=3.1.2
28
28
  Requires-Dist: json-repair<1.0.0,>=0.29.9
29
29
  Requires-Dist: lxml<5.0.0,>=4.9.3
30
+ Requires-Dist: markdownify>=0.13.1
30
31
  Requires-Dist: nest-asyncio<2.0.0,>=1.6.0
31
32
  Requires-Dist: nltk<4.0.0,>=3.8.2
32
33
  Requires-Dist: onnxruntime<2.0.0,>=1.16.1
@@ -174,7 +174,7 @@ class DocChatAgentConfig(ChatAgentConfig):
174
174
  "https://ai.googleblog.com/2022/11/characterizing-emergent-phenomena-in.html",
175
175
  ]
176
176
  parsing: ParsingConfig = ParsingConfig( # modify as needed
177
- splitter=Splitter.TOKENS,
177
+ splitter=Splitter.MARKDOWN,
178
178
  chunk_size=1000, # aim for this many tokens per chunk
179
179
  overlap=100, # overlap between chunks
180
180
  max_chunks=10_000,
@@ -1059,8 +1059,8 @@ class OpenAIGPT(LanguageModel):
1059
1059
  )
1060
1060
  if is_break:
1061
1061
  break
1062
- except Exception:
1063
- pass
1062
+ except Exception as e:
1063
+ logging.warning("Error while processing stream response: %s", str(e))
1064
1064
 
1065
1065
  print("")
1066
1066
  # TODO- get usage info in stream mode (?)
@@ -1121,8 +1121,8 @@ class OpenAIGPT(LanguageModel):
1121
1121
  )
1122
1122
  if is_break:
1123
1123
  break
1124
- except Exception:
1125
- pass
1124
+ except Exception as e:
1125
+ logging.warning("Error while processing stream response: %s", str(e))
1126
1126
 
1127
1127
  print("")
1128
1128
  # TODO- get usage info in stream mode (?)
@@ -1703,11 +1703,32 @@ class OpenAIGPT(LanguageModel):
1703
1703
  if self.config.litellm and settings.debug:
1704
1704
  kwargs["logger_fn"] = litellm_logging_fn
1705
1705
  result = completion_call(**kwargs)
1706
- if not self.get_stream():
1707
- # if streaming, cannot cache result
1706
+
1707
+ if self.get_stream():
1708
+ # If streaming, cannot cache result
1708
1709
  # since it is a generator. Instead,
1709
1710
  # we hold on to the hashed_key and
1710
1711
  # cache the result later
1712
+
1713
+ # Test if this is a stream with an exception by
1714
+ # trying to get first chunk: Some providers like LiteLLM
1715
+ # produce a valid stream object `result` instead of throwing a
1716
+ # rate-limit error, and if we don't catch it here,
1717
+ # we end up returning an empty response and not
1718
+ # using the retry mechanism in the decorator.
1719
+ try:
1720
+ # try to get the first chunk to check for errors
1721
+ test_iter = iter(result)
1722
+ first_chunk = next(test_iter)
1723
+ # If we get here without error, recreate the stream
1724
+ result = chain([first_chunk], test_iter)
1725
+ except StopIteration:
1726
+ # Empty stream is fine
1727
+ pass
1728
+ except Exception as e:
1729
+ # Propagate any errors in the stream
1730
+ raise e
1731
+ else:
1711
1732
  self._cache_store(hashed_key, result.model_dump())
1712
1733
  return cached, hashed_key, result
1713
1734
 
@@ -1734,7 +1755,35 @@ class OpenAIGPT(LanguageModel):
1734
1755
  kwargs["logger_fn"] = litellm_logging_fn
1735
1756
  # If it's not in the cache, call the API
1736
1757
  result = await acompletion_call(**kwargs)
1737
- if not self.get_stream():
1758
+ if self.get_stream():
1759
+ try:
1760
+ # Try to peek at the first chunk to immediately catch any errors
1761
+ # Store the original result (the stream)
1762
+ original_stream = result
1763
+
1764
+ # Manually create and advance the iterator to check for errors
1765
+ stream_iter = original_stream.__aiter__()
1766
+ try:
1767
+ # This will raise an exception if the stream is invalid
1768
+ first_chunk = await anext(stream_iter)
1769
+
1770
+ # If we reach here, the stream started successfully
1771
+ # Now recreate a fresh stream from the original API result
1772
+ # Otherwise, return a new stream that yields the first chunk
1773
+ # and remaining items
1774
+ async def combined_stream(): # type: ignore
1775
+ yield first_chunk
1776
+ async for chunk in stream_iter:
1777
+ yield chunk
1778
+
1779
+ result = combined_stream() # type: ignore
1780
+ except StopAsyncIteration:
1781
+ # Empty stream is normal - nothing to do
1782
+ pass
1783
+ except Exception as e:
1784
+ # Any exception here should be raised to trigger the retry mechanism
1785
+ raise e
1786
+ else:
1738
1787
  self._cache_store(hashed_key, result.model_dump())
1739
1788
  return cached, hashed_key, result
1740
1789
 
@@ -65,6 +65,33 @@ class DocMetaData(BaseModel):
65
65
 
66
66
  return original_dict
67
67
 
68
+ def __str__(self) -> str:
69
+ title_str = (
70
+ ""
71
+ if "unknown" in self.title.lower() or self.title.strip() == ""
72
+ else f"Title: {self.title}"
73
+ )
74
+ date_str = ""
75
+ if (
76
+ "unknown" not in self.published_date.lower()
77
+ and self.published_date.strip() != ""
78
+ ):
79
+ try:
80
+ from dateutil import parser
81
+
82
+ # Try to parse the date string
83
+ date_obj = parser.parse(self.published_date)
84
+ # Format to include only the date part (year-month-day)
85
+ date_only = date_obj.strftime("%Y-%m-%d")
86
+ date_str = f"Date: {date_only}"
87
+ except (ValueError, ImportError, TypeError):
88
+ # If parsing fails, just use the original date
89
+ date_str = f"Date: {self.published_date}"
90
+ components = [self.source] + (
91
+ [] if title_str + date_str == "" else [title_str, date_str]
92
+ )
93
+ return ", ".join(components)
94
+
68
95
  class Config:
69
96
  extra = Extra.allow
70
97
 
@@ -93,7 +120,7 @@ class Document(BaseModel):
93
120
  return dedent(
94
121
  f"""
95
122
  CONTENT: {self.content}
96
- SOURCE:{self.metadata.source}
123
+ SOURCE:{str(self.metadata)}
97
124
  """
98
125
  )
99
126
 
@@ -380,9 +380,6 @@ class DocumentParser(Parser):
380
380
  Get document chunks from a pdf source,
381
381
  with page references in the document metadata.
382
382
 
383
- Adapted from
384
- https://github.com/whitead/paper-qa/blob/main/paperqa/readers.py
385
-
386
383
  Returns:
387
384
  List[Document]: a list of `Document` objects,
388
385
  each containing a chunk of text