langroid 0.1.144__py3-none-any.whl → 0.1.145__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.
@@ -789,12 +789,14 @@ class ChatAgent(Agent):
789
789
  """
790
790
  # explicitly call THIS class's respond method,
791
791
  # not a derived class's (or else there would be infinite recursion!)
792
+ n_msgs = len(self.message_history)
792
793
  with StreamingIfAllowed(self.llm, self.llm.get_stream()): # type: ignore
793
794
  response = cast(ChatDocument, ChatAgent.llm_response(self, message))
794
- # clear the last two messages, which are the
795
- # user message and the assistant response
796
- self.message_history.pop()
797
- self.message_history.pop()
795
+ # If there is a response, then we will have two additional
796
+ # messages in the message history, i.e. the user message and the
797
+ # assistant response. We want to (carefully) remove these two messages.
798
+ self.message_history.pop() if len(self.message_history) > n_msgs else None
799
+ self.message_history.pop() if len(self.message_history) > n_msgs else None
798
800
  return response
799
801
 
800
802
  async def llm_response_forget_async(self, message: str) -> ChatDocument:
@@ -803,14 +805,16 @@ class ChatAgent(Agent):
803
805
  """
804
806
  # explicitly call THIS class's respond method,
805
807
  # not a derived class's (or else there would be infinite recursion!)
808
+ n_msgs = len(self.message_history)
806
809
  with StreamingIfAllowed(self.llm, self.llm.get_stream()): # type: ignore
807
810
  response = cast(
808
811
  ChatDocument, await ChatAgent.llm_response_async(self, message)
809
812
  )
810
- # clear the last two messages, which are the
811
- # user message and the assistant response
812
- self.message_history.pop()
813
- self.message_history.pop()
813
+ # If there is a response, then we will have two additional
814
+ # messages in the message history, i.e. the user message and the
815
+ # assistant response. We want to (carefully) remove these two messages.
816
+ self.message_history.pop() if len(self.message_history) > n_msgs else None
817
+ self.message_history.pop() if len(self.message_history) > n_msgs else None
814
818
  return response
815
819
 
816
820
  def chat_num_tokens(self, messages: Optional[List[LLMMessage]] = None) -> int:
@@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
28
28
 
29
29
 
30
30
  class RecordMetadata(DocMetaData):
31
- id: None | str = None
31
+ id: str = ""
32
32
 
33
33
 
34
34
  class RecordDoc(Document):
@@ -469,6 +469,7 @@ class OpenAIGPT(LanguageModel):
469
469
  return True, has_function, function_name, function_args, completion
470
470
  return False, has_function, function_name, function_args, completion
471
471
 
472
+ @retry_with_exponential_backoff
472
473
  def _stream_response( # type: ignore
473
474
  self, response, chat: bool = False
474
475
  ) -> Tuple[LLMResponse, Dict[str, Any]]:
@@ -520,6 +521,7 @@ class OpenAIGPT(LanguageModel):
520
521
  is_async=False,
521
522
  )
522
523
 
524
+ @async_retry_with_exponential_backoff
523
525
  async def _stream_response_async( # type: ignore
524
526
  self, response, chat: bool = False
525
527
  ) -> Tuple[LLMResponse, Dict[str, Any]]:
@@ -1084,7 +1086,7 @@ class OpenAIGPT(LanguageModel):
1084
1086
  if self.get_stream() and not cached:
1085
1087
  llm_response, openai_response = self._stream_response(response, chat=True)
1086
1088
  self._cache_store(hashed_key, openai_response)
1087
- return llm_response
1089
+ return llm_response # type: ignore
1088
1090
  if isinstance(response, dict):
1089
1091
  response_dict = response
1090
1092
  else:
@@ -1115,7 +1117,7 @@ class OpenAIGPT(LanguageModel):
1115
1117
  response, chat=True
1116
1118
  )
1117
1119
  self._cache_store(hashed_key, openai_response)
1118
- return llm_response
1120
+ return llm_response # type: ignore
1119
1121
  if isinstance(response, dict):
1120
1122
  response_dict = response
1121
1123
  else:
langroid/mytypes.py CHANGED
@@ -27,12 +27,12 @@ class DocMetaData(BaseModel):
27
27
 
28
28
  source: str = "context"
29
29
  is_chunk: bool = False # if it is a chunk, don't split
30
- id: str | None = None # unique id for the document
30
+ id: str = "" # unique id for the document
31
31
  window_ids: List[str] = [] # for RAG: ids of chunks around this one
32
32
 
33
- def dict(self, *args: Any, **kwargs: Any) -> Dict[str, Any]:
33
+ def dict_bool_int(self, *args: Any, **kwargs: Any) -> Dict[str, Any]:
34
34
  """
35
- Override dict method to convert bool fields to int, to appease some
35
+ Special dict method to convert bool fields to int, to appease some
36
36
  downstream libraries, e.g. Chroma which complains about bool fields in
37
37
  metadata.
38
38
  """
@@ -65,8 +65,8 @@ class Parser:
65
65
  orig_id_to_ids: Dict[str, List[str]] = {}
66
66
  for orig_id, id in zip(orig_ids, ids):
67
67
  if orig_id not in orig_id_to_ids:
68
- orig_id_to_ids[orig_id] = [] # type: ignore
69
- orig_id_to_ids[orig_id].append(id) # type: ignore
68
+ orig_id_to_ids[orig_id] = []
69
+ orig_id_to_ids[orig_id].append(id)
70
70
 
71
71
  # now each orig_id maps to a sequence of ids within a single doc
72
72
 
@@ -114,7 +114,9 @@ class ChromaDB(VectorStore):
114
114
  return
115
115
  contents: List[str] = [document.content for document in documents]
116
116
  # convert metadatas to dicts so chroma can handle them
117
- metadata_dicts: List[dict[str, Any]] = [d.metadata.dict() for d in documents]
117
+ metadata_dicts: List[dict[str, Any]] = [
118
+ d.metadata.dict_bool_int() for d in documents
119
+ ]
118
120
  for m in metadata_dicts:
119
121
  # chroma does not handle non-atomic types in metadata
120
122
  m["window_ids"] = ",".join(m["window_ids"])
@@ -14,9 +14,7 @@ from langroid.embedding_models.models import OpenAIEmbeddingsConfig
14
14
  from langroid.mytypes import Document, EmbeddingFunction
15
15
  from langroid.utils.configuration import settings
16
16
  from langroid.utils.pydantic_utils import (
17
- flatten_pydantic_instance,
18
17
  flatten_pydantic_model,
19
- nested_dict_from_flat,
20
18
  )
21
19
  from langroid.vector_store.base import VectorStore, VectorStoreConfig
22
20
 
@@ -191,7 +189,7 @@ class LanceDB(VectorStore):
191
189
  else:
192
190
  logger.warning("Recreating fresh collection")
193
191
  tbl = self.client.create_table(
194
- collection_name, schema=self.flat_schema, mode="overwrite"
192
+ collection_name, schema=self.schema, mode="overwrite"
195
193
  )
196
194
  if settings.debug:
197
195
  level = logger.getEffectiveLevel()
@@ -217,12 +215,10 @@ class LanceDB(VectorStore):
217
215
  def make_batches() -> Generator[List[Dict[str, Any]], None, None]:
218
216
  for i in range(0, len(ids), b):
219
217
  yield [
220
- flatten_pydantic_instance(
221
- self.schema(
222
- id=ids[i],
223
- vector=embedding_vecs[i],
224
- payload=doc,
225
- )
218
+ self.schema( # type: ignore
219
+ id=ids[i],
220
+ vector=embedding_vecs[i],
221
+ payload=doc,
226
222
  )
227
223
  for i, doc in enumerate(documents[i : i + b])
228
224
  ]
@@ -238,12 +234,8 @@ class LanceDB(VectorStore):
238
234
  raise ValueError("No collection name set, cannot retrieve docs")
239
235
  tbl = self.client.open_table(self.config.collection_name)
240
236
  records = tbl.search(None).to_arrow().to_pylist()
241
- docs = [
242
- self.config.document_class(
243
- **(nested_dict_from_flat(rec, sub_dict="payload"))
244
- )
245
- for rec in records
246
- ]
237
+ doc_cls = self.config.document_class
238
+ docs = [doc_cls(**rec["payload"]) for rec in records]
247
239
  return docs
248
240
 
249
241
  def get_documents_by_ids(self, ids: List[str]) -> List[Document]:
@@ -256,10 +248,7 @@ class LanceDB(VectorStore):
256
248
  for _id in _ids
257
249
  ]
258
250
  doc_cls = self.config.document_class
259
- docs = [
260
- doc_cls(**(nested_dict_from_flat(rec, sub_dict="payload")))
261
- for rec in records
262
- ]
251
+ docs = [doc_cls(**rec["payload"]) for rec in records]
263
252
  return docs
264
253
 
265
254
  def similar_texts_with_scores(
@@ -281,12 +270,7 @@ class LanceDB(VectorStore):
281
270
 
282
271
  # note _distance is 1 - cosine
283
272
  scores = [1 - rec["_distance"] for rec in records]
284
- docs = [
285
- self.config.document_class(
286
- **(nested_dict_from_flat(rec, sub_dict="payload"))
287
- )
288
- for rec in records
289
- ]
273
+ docs = [self.config.document_class(**rec["payload"]) for rec in records]
290
274
  if len(docs) == 0:
291
275
  logger.warning(f"No matches found for {text}")
292
276
  return []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.1.144
3
+ Version: 0.1.145
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -29,7 +29,7 @@ Requires-Dist: flake8 (>=6.0.0,<7.0.0)
29
29
  Requires-Dist: google-api-python-client (>=2.95.0,<3.0.0)
30
30
  Requires-Dist: halo (>=0.0.31,<0.0.32)
31
31
  Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
32
- Requires-Dist: lancedb (>=0.3.0,<0.4.0)
32
+ Requires-Dist: lancedb (>=0.3.6,<0.4.0)
33
33
  Requires-Dist: litellm (>=1.0.0,<2.0.0) ; extra == "litellm"
34
34
  Requires-Dist: lxml (>=4.9.3,<5.0.0)
35
35
  Requires-Dist: meilisearch (>=0.28.3,<0.29.0)
@@ -2,7 +2,7 @@ langroid/__init__.py,sha256=-T6zCLCy-0U_h4iDmC2d6OUXjqopFe0XGrclYgbnBZk,465
2
2
  langroid/agent/__init__.py,sha256=ZqDw3Ktw7XGDl6mC8DN61F71V4ckf0rBoEOydH9l6C4,428
3
3
  langroid/agent/base.py,sha256=2xnNig9pRv5IJR-_up5QwRrX7UYMeP56BYf1MDDY0n0,31982
4
4
  langroid/agent/batch.py,sha256=Cg7Qv1yGi_M9rMl38_4-hjXPsoLlZrOSXDhbOFqUcKY,5593
5
- langroid/agent/chat_agent.py,sha256=B9DPToPXyDdGf2MUK4ahCkqsawPjNGwoiyZXH8TTFYQ,35114
5
+ langroid/agent/chat_agent.py,sha256=yK56EAuT-RxRWBbfVaevl0qW1h8neWL0lktPQc34uUc,35626
6
6
  langroid/agent/chat_document.py,sha256=dw0m_00qJgOhbzCkEsVBAiktM6BJ62mV8_piu5GruXM,7008
7
7
  langroid/agent/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  langroid/agent/junk,sha256=LxfuuW7Cijsg0szAzT81OjWWv1PMNI-6w_-DspVIO2s,339
@@ -11,7 +11,7 @@ langroid/agent/special/__init__.py,sha256=Iex-fxO7sTM2LKAOk-JQLzovk-zlzqi5PwxiMB
11
11
  langroid/agent/special/doc_chat_agent.py,sha256=ERZs1phXGA_18114d7qv_Zl4-TPte-z2v6dgA75RAq0,37264
12
12
  langroid/agent/special/recipient_validator_agent.py,sha256=WmLnQUdkrvWLDfFeS3Q7CnrfkDk0-trQxitQSuR7fpE,6315
13
13
  langroid/agent/special/relevance_extractor_agent.py,sha256=19LwSZ09q8LyiU-iKrOOuG0uboyoUBVL3zXeteHKiLs,4162
14
- langroid/agent/special/retriever_agent.py,sha256=ze8jXJW9A_twsrRXVECAQCYicfjm8-a6qv1vDk41AAc,6573
14
+ langroid/agent/special/retriever_agent.py,sha256=wUCm0PAzHNn4aGb2Q-7dwYIAxX2_RwrZQenwDeGxOIg,6564
15
15
  langroid/agent/special/sql/__init__.py,sha256=3kR5nC0wnYIzmMrr9L8RJa7JAJpbwBLx7KKygiwz0v0,111
16
16
  langroid/agent/special/sql/sql_chat_agent.py,sha256=Ua_gfK_1k5ct59Zkbe78bzs-2jabtFkEVx76a0pGs9Y,12867
17
17
  langroid/agent/special/sql/utils/__init__.py,sha256=_IBHt3iNXvPqxvDrs5_T86qdj0gPugVGnGNi6Cx7F-I,238
@@ -43,12 +43,12 @@ langroid/language_models/azure_openai.py,sha256=_OOEoZOziI3NDOH_8t3qmh8IDWoHESQe
43
43
  langroid/language_models/base.py,sha256=jUEUqDWJBVxIxmG6U4Ysg2QKGOnP_CLmRuEMicsSwUw,20596
44
44
  langroid/language_models/config.py,sha256=PXcmEUq52GCDj2sekt8F9E1flWyyNjP2S0LTRs7T6Kg,269
45
45
  langroid/language_models/openai_assistants.py,sha256=9K-DEAL2aSWHeXj2hwCo2RAlK9_1oCPtqX2u1wISCj8,36
46
- langroid/language_models/openai_gpt.py,sha256=QBOtB0gqIMRs5rjb9H8qjetYXWFMgvQkCcxeWBh5w6g,42094
46
+ langroid/language_models/openai_gpt.py,sha256=K3UtPVrd6OdpsGnYfb2EwMiS6XqpHFivwb3oATbus8k,42204
47
47
  langroid/language_models/prompt_formatter/__init__.py,sha256=wj2e6j7R9d3m63HCbSDY1vosjFuhHLQVlgBrq8iqF38,197
48
48
  langroid/language_models/prompt_formatter/base.py,sha256=2y_GcwhstvB5ih3haS7l5Fv79jVnFJ_vEw1jqWJzB9k,1247
49
49
  langroid/language_models/prompt_formatter/llama2_formatter.py,sha256=YdcO88qyBeuMENVIVvVqSYuEpvYSTndUe_jd6hVTko4,2899
50
50
  langroid/language_models/utils.py,sha256=3stQOt3sAdbGT70thurlxfnQ4xPxH75YjFm-jaRuXlg,4474
51
- langroid/mytypes.py,sha256=n43j4bmJLJybhvq6SIQm65Dfgbz2gOgru4Zj9zNEWYI,2502
51
+ langroid/mytypes.py,sha256=-0q-SyicLbdjFSIEcwt5u-EwhRcMWllSoWYE3OWk78M,2501
52
52
  langroid/parsing/__init__.py,sha256=_EZ8iuixxU39zuaydtfjyap8g9C_c1dnrCQ0QR81U2E,340
53
53
  langroid/parsing/agent_chats.py,sha256=sbZRV9ujdM5QXvvuHVjIi2ysYSYlap-uqfMMUKulrW0,1068
54
54
  langroid/parsing/code-parsing.md,sha256=--cyyNiSZSDlIwcjAV4-shKrSiRe2ytF3AdSoS_hD2g,3294
@@ -57,7 +57,7 @@ langroid/parsing/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  langroid/parsing/document_parser.py,sha256=YC3IXQ9ErpBGBZh6Be9gfJWHcTwGTSMfNQMT5ARrj5g,14615
58
58
  langroid/parsing/json.py,sha256=MVqBUfInALQm1QKbcfEvLzWxBz_UztCIyGk7AK5uFPo,1650
59
59
  langroid/parsing/para_sentence_split.py,sha256=AJBzZojP3zpB-_IMiiHismhqcvkrVBQ3ZINoQyx_bE4,2000
60
- langroid/parsing/parser.py,sha256=qbIsXS62s_JbzwVjyG6g4ly_Y4GHao6k2gykCY214P4,10283
60
+ langroid/parsing/parser.py,sha256=BwVJboobG71N08w5LC7Tu36LI4pEJoSgAdiBSLChWGY,10251
61
61
  langroid/parsing/repo_loader.py,sha256=4qCyRRHCKIYd8F1ghT-D8ko1C2sXpF7UYP1L5Im1hRE,27705
62
62
  langroid/parsing/search.py,sha256=xmQdAdTIwZ0REEUeQVFlGZlqf7k8Poah7-ALuyW7Ov0,8440
63
63
  langroid/parsing/spider.py,sha256=w_mHR1B4KOmxsBLoVI8kMkMTEbwTzeK3ath9fOMJrTk,3043
@@ -91,13 +91,13 @@ langroid/utils/web/login.py,sha256=1iz9eUAHa87vpKIkzwkmFa00avwFWivDSAr7QUhK7U0,2
91
91
  langroid/utils/web/selenium_login.py,sha256=mYI6EvVmne34N9RajlsxxRqJQJvV-WG4LGp6sEECHPw,1156
92
92
  langroid/vector_store/__init__.py,sha256=NhAXOCKX_x2whfghOn44e0O3-vV0nJRz6ZLsCBqYFyQ,242
93
93
  langroid/vector_store/base.py,sha256=60XkAcX7OLkseYE66p3XOcXs7KB9udJbOV5IBfzNBDs,12188
94
- langroid/vector_store/chromadb.py,sha256=5v9fbj5exHRrCayo4Qlw1wF8QnfMd3ubtwbOXcYydIs,7094
95
- langroid/vector_store/lancedb.py,sha256=2ckggSZnX-FI5-dV7KgIqeufDTtEFlnfTKKsuEKAOZo,11293
94
+ langroid/vector_store/chromadb.py,sha256=tQ_qNWgboLpZs4MG21za9QYIUc6fNQe2XmTBjSn6_ak,7125
95
+ langroid/vector_store/lancedb.py,sha256=NWG2OS51jL141ATu6L4AVPECShBiR4GD2BW0ZQVnzf0,10919
96
96
  langroid/vector_store/meilisearch.py,sha256=kxPtvZ3_fM8NxILps1nI50YbpJP6KqhAfY3idwcblh8,11238
97
97
  langroid/vector_store/momento.py,sha256=91Ep3OVkGzDM60aPT1Y_Da5SS1_1lrR9no-CNzHrBoY,10027
98
98
  langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
99
99
  langroid/vector_store/qdrantdb.py,sha256=CcIAGale7LO7V_4CeRihIUKqlwi4LxUldtwPKVOvgUg,11848
100
- langroid-0.1.144.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
101
- langroid-0.1.144.dist-info/METADATA,sha256=O9QT2pGCot6fETr6xOBG5dw-YpFv0Vs9BDmn0LrSel4,41526
102
- langroid-0.1.144.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
103
- langroid-0.1.144.dist-info/RECORD,,
100
+ langroid-0.1.145.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
101
+ langroid-0.1.145.dist-info/METADATA,sha256=YNfr4Ceiwock4mAgZorQouU6oUhPgxczKleXWn36GnY,41526
102
+ langroid-0.1.145.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
103
+ langroid-0.1.145.dist-info/RECORD,,