langroid 0.34.0__py3-none-any.whl → 0.35.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.
@@ -117,6 +117,7 @@ class ChatDocument(Document):
117
117
  attachment (None | ChatDocAttachment): Any additional data attached.
118
118
  """
119
119
 
120
+ reasoning: str = "" # reasoning produced by a reasoning LLM
120
121
  content_any: Any = None # to hold arbitrary data returned by responders
121
122
  oai_tool_calls: Optional[List[OpenAIToolCall]] = None
122
123
  oai_tool_id2result: Optional[OrderedDict[str, str]] = None
@@ -297,6 +298,7 @@ class ChatDocument(Document):
297
298
  ChatDocument._clean_fn_call(oai_tc.function)
298
299
  return ChatDocument(
299
300
  content=message,
301
+ reasoning=response.reasoning,
300
302
  content_any=message,
301
303
  oai_tool_calls=response.oai_tool_calls,
302
304
  function_call=response.function_call,
@@ -72,14 +72,13 @@ def apply_nest_asyncio() -> None:
72
72
 
73
73
  logger = logging.getLogger(__name__)
74
74
 
75
- DEFAULT_DOC_CHAT_INSTRUCTIONS = """
76
- Your task is to answer questions about various documents.
77
- You will be given various passages from these documents, and asked to answer questions
78
- about them, or summarize them into coherent answers.
79
- """
80
75
 
81
76
  DEFAULT_DOC_CHAT_SYSTEM_MESSAGE = """
82
77
  You are a helpful assistant, helping me understand a collection of documents.
78
+
79
+ Your TASK is to answer questions about various documents.
80
+ You will be given various passages from these documents, and asked to answer questions
81
+ about them, or summarize them into coherent answers.
83
82
  """
84
83
 
85
84
  CHUNK_ENRICHMENT_DELIMITER = "<##-##-##>"
@@ -113,7 +112,6 @@ class ChunkEnrichmentAgentConfig(ChatAgentConfig):
113
112
 
114
113
  class DocChatAgentConfig(ChatAgentConfig):
115
114
  system_message: str = DEFAULT_DOC_CHAT_SYSTEM_MESSAGE
116
- user_message: str = DEFAULT_DOC_CHAT_INSTRUCTIONS
117
115
  summarize_prompt: str = SUMMARY_ANSWER_PROMPT_GPT4
118
116
  # extra fields to include in content as key=value pairs
119
117
  # (helps retrieval for table-like data)
@@ -214,6 +212,12 @@ class DocChatAgentConfig(ChatAgentConfig):
214
212
  )
215
213
 
216
214
 
215
+ def _append_metadata_source(orig_source: str, source: str) -> str:
216
+ if orig_source != source and source != "" and orig_source != "":
217
+ return f"{orig_source.strip()}; {source.strip()}"
218
+ return orig_source.strip() + source.strip()
219
+
220
+
217
221
  class DocChatAgent(ChatAgent):
218
222
  """
219
223
  Agent for chatting with a collection of documents.
@@ -339,7 +343,11 @@ class DocChatAgent(ChatAgent):
339
343
  url_docs = loader.load()
340
344
  # update metadata of each doc with meta
341
345
  for d in url_docs:
346
+ orig_source = d.metadata.source
342
347
  d.metadata = d.metadata.copy(update=meta)
348
+ d.metadata.source = _append_metadata_source(
349
+ orig_source, meta.get("source", "")
350
+ )
343
351
  docs.extend(url_docs)
344
352
  if len(paths) > 0: # paths OR bytes are handled similarly
345
353
  for pi in path_idxs:
@@ -352,7 +360,11 @@ class DocChatAgent(ChatAgent):
352
360
  )
353
361
  # update metadata of each doc with meta
354
362
  for d in path_docs:
363
+ orig_source = d.metadata.source
355
364
  d.metadata = d.metadata.copy(update=meta)
365
+ d.metadata.source = _append_metadata_source(
366
+ orig_source, meta.get("source", "")
367
+ )
356
368
  docs.extend(path_docs)
357
369
  n_docs = len(docs)
358
370
  n_splits = self.ingest_docs(docs, split=self.config.split)
@@ -393,15 +405,26 @@ class DocChatAgent(ChatAgent):
393
405
  """
394
406
  if isinstance(metadata, list) and len(metadata) > 0:
395
407
  for d, m in zip(docs, metadata):
396
- d.metadata = d.metadata.copy(
397
- update=m if isinstance(m, dict) else m.dict() # type: ignore
408
+ orig_source = d.metadata.source
409
+ m_dict = m if isinstance(m, dict) else m.dict() # type: ignore
410
+ d.metadata = d.metadata.copy(update=m_dict) # type: ignore
411
+ d.metadata.source = _append_metadata_source(
412
+ orig_source, m_dict.get("source", "")
398
413
  )
399
414
  elif isinstance(metadata, dict):
400
415
  for d in docs:
416
+ orig_source = d.metadata.source
401
417
  d.metadata = d.metadata.copy(update=metadata)
418
+ d.metadata.source = _append_metadata_source(
419
+ orig_source, metadata.get("source", "")
420
+ )
402
421
  elif isinstance(metadata, DocMetaData):
403
422
  for d in docs:
423
+ orig_source = d.metadata.source
404
424
  d.metadata = d.metadata.copy(update=metadata.dict())
425
+ d.metadata.source = _append_metadata_source(
426
+ orig_source, metadata.source
427
+ )
405
428
 
406
429
  self.original_docs.extend(docs)
407
430
  if self.parser is None:
@@ -75,6 +75,8 @@ class LLMConfig(BaseSettings):
75
75
  # use chat model for completion? For OpenAI models, this MUST be set to True!
76
76
  use_chat_for_completion: bool = True
77
77
  stream: bool = True # stream output from API?
78
+ # TODO: we could have a `stream_reasoning` flag here to control whether to show
79
+ # reasoning output from reasoning models
78
80
  cache_config: None | CacheDBConfig = RedisCacheConfig()
79
81
 
80
82
  # Dict of model -> (input/prompt cost, output/completion cost)
@@ -317,6 +319,7 @@ class LLMResponse(BaseModel):
317
319
  """
318
320
 
319
321
  message: str
322
+ reasoning: str = "" # optional reasoning text from reasoning models
320
323
  # TODO tool_id needs to generalize to multi-tool calls
321
324
  tool_id: str = "" # used by OpenAIAssistant
322
325
  oai_tool_calls: Optional[List[OpenAIToolCall]] = None
@@ -820,6 +820,7 @@ class OpenAIGPT(LanguageModel):
820
820
  tool_deltas: List[Dict[str, Any]] = [],
821
821
  has_function: bool = False,
822
822
  completion: str = "",
823
+ reasoning: str = "",
823
824
  function_args: str = "",
824
825
  function_name: str = "",
825
826
  ) -> Tuple[bool, bool, str, str]:
@@ -845,7 +846,9 @@ class OpenAIGPT(LanguageModel):
845
846
  # In the 1st: choices list is empty, in the 2nd: the dict delta has null content
846
847
  if chat:
847
848
  delta = choices[0].get("delta", {})
849
+ # capture both content and reasoning_content
848
850
  event_text = delta.get("content", "")
851
+ event_reasoning = delta.get("reasoning_content", "")
849
852
  if "function_call" in delta and delta["function_call"] is not None:
850
853
  if "name" in delta["function_call"]:
851
854
  event_fn_name = delta["function_call"]["name"]
@@ -857,6 +860,7 @@ class OpenAIGPT(LanguageModel):
857
860
  tool_deltas += event_tool_deltas
858
861
  else:
859
862
  event_text = choices[0]["text"]
863
+ event_reasoning = "" # TODO: Ignoring reasoning for non-chat models
860
864
 
861
865
  finish_reason = choices[0].get("finish_reason", "")
862
866
  if not event_text and finish_reason == "content_filter":
@@ -877,6 +881,11 @@ class OpenAIGPT(LanguageModel):
877
881
  sys.stdout.write(Colors().GREEN + event_text)
878
882
  sys.stdout.flush()
879
883
  self.config.streamer(event_text, StreamEventType.TEXT)
884
+ if event_reasoning:
885
+ reasoning += event_reasoning
886
+ sys.stdout.write(Colors().GREEN_DIM + event_reasoning)
887
+ sys.stdout.flush()
888
+ self.config.streamer(event_reasoning, StreamEventType.TEXT)
880
889
  if event_fn_name:
881
890
  function_name = event_fn_name
882
891
  has_function = True
@@ -915,8 +924,15 @@ class OpenAIGPT(LanguageModel):
915
924
  # for function_call, finish_reason does not necessarily
916
925
  # contain "function_call" as mentioned in the docs.
917
926
  # So we check for "stop" or "function_call" here.
918
- return True, has_function, function_name, function_args, completion
919
- return False, has_function, function_name, function_args, completion
927
+ return (
928
+ True,
929
+ has_function,
930
+ function_name,
931
+ function_args,
932
+ completion,
933
+ reasoning,
934
+ )
935
+ return False, has_function, function_name, function_args, completion, reasoning
920
936
 
921
937
  @no_type_check
922
938
  async def _process_stream_event_async(
@@ -926,6 +942,7 @@ class OpenAIGPT(LanguageModel):
926
942
  tool_deltas: List[Dict[str, Any]] = [],
927
943
  has_function: bool = False,
928
944
  completion: str = "",
945
+ reasoning: str = "",
929
946
  function_args: str = "",
930
947
  function_name: str = "",
931
948
  ) -> Tuple[bool, bool, str, str]:
@@ -953,6 +970,7 @@ class OpenAIGPT(LanguageModel):
953
970
  if chat:
954
971
  delta = choices[0].get("delta", {})
955
972
  event_text = delta.get("content", "")
973
+ event_reasoning = delta.get("reasoning_content", "")
956
974
  if "function_call" in delta and delta["function_call"] is not None:
957
975
  if "name" in delta["function_call"]:
958
976
  event_fn_name = delta["function_call"]["name"]
@@ -964,12 +982,19 @@ class OpenAIGPT(LanguageModel):
964
982
  tool_deltas += event_tool_deltas
965
983
  else:
966
984
  event_text = choices[0]["text"]
985
+ event_reasoning = "" # TODO: Ignoring reasoning for non-chat models
967
986
  if event_text:
968
987
  completion += event_text
969
988
  if not silent:
970
989
  sys.stdout.write(Colors().GREEN + event_text)
971
990
  sys.stdout.flush()
972
991
  await self.config.streamer_async(event_text, StreamEventType.TEXT)
992
+ if event_reasoning:
993
+ reasoning += event_reasoning
994
+ if not silent:
995
+ sys.stdout.write(Colors().GREEN + event_reasoning)
996
+ sys.stdout.flush()
997
+ await self.config.streamer_async(event_reasoning, StreamEventType.TEXT)
973
998
  if event_fn_name:
974
999
  function_name = event_fn_name
975
1000
  has_function = True
@@ -1016,8 +1041,15 @@ class OpenAIGPT(LanguageModel):
1016
1041
  # for function_call, finish_reason does not necessarily
1017
1042
  # contain "function_call" as mentioned in the docs.
1018
1043
  # So we check for "stop" or "function_call" here.
1019
- return True, has_function, function_name, function_args, completion
1020
- return False, has_function, function_name, function_args, completion
1044
+ return (
1045
+ True,
1046
+ has_function,
1047
+ function_name,
1048
+ function_args,
1049
+ completion,
1050
+ reasoning,
1051
+ )
1052
+ return False, has_function, function_name, function_args, completion, reasoning
1021
1053
 
1022
1054
  @retry_with_exponential_backoff
1023
1055
  def _stream_response( # type: ignore
@@ -1035,6 +1067,7 @@ class OpenAIGPT(LanguageModel):
1035
1067
 
1036
1068
  """
1037
1069
  completion = ""
1070
+ reasoning = ""
1038
1071
  function_args = ""
1039
1072
  function_name = ""
1040
1073
 
@@ -1050,12 +1083,14 @@ class OpenAIGPT(LanguageModel):
1050
1083
  function_name,
1051
1084
  function_args,
1052
1085
  completion,
1086
+ reasoning,
1053
1087
  ) = self._process_stream_event(
1054
1088
  event,
1055
1089
  chat=chat,
1056
1090
  tool_deltas=tool_deltas,
1057
1091
  has_function=has_function,
1058
1092
  completion=completion,
1093
+ reasoning=reasoning,
1059
1094
  function_args=function_args,
1060
1095
  function_name=function_name,
1061
1096
  )
@@ -1072,6 +1107,7 @@ class OpenAIGPT(LanguageModel):
1072
1107
  tool_deltas=tool_deltas,
1073
1108
  has_function=has_function,
1074
1109
  completion=completion,
1110
+ reasoning=reasoning,
1075
1111
  function_args=function_args,
1076
1112
  function_name=function_name,
1077
1113
  )
@@ -1092,6 +1128,7 @@ class OpenAIGPT(LanguageModel):
1092
1128
 
1093
1129
  """
1094
1130
  completion = ""
1131
+ reasoning = ""
1095
1132
  function_args = ""
1096
1133
  function_name = ""
1097
1134
 
@@ -1107,12 +1144,14 @@ class OpenAIGPT(LanguageModel):
1107
1144
  function_name,
1108
1145
  function_args,
1109
1146
  completion,
1147
+ reasoning,
1110
1148
  ) = await self._process_stream_event_async(
1111
1149
  event,
1112
1150
  chat=chat,
1113
1151
  tool_deltas=tool_deltas,
1114
1152
  has_function=has_function,
1115
1153
  completion=completion,
1154
+ reasoning=reasoning,
1116
1155
  function_args=function_args,
1117
1156
  function_name=function_name,
1118
1157
  )
@@ -1129,6 +1168,7 @@ class OpenAIGPT(LanguageModel):
1129
1168
  tool_deltas=tool_deltas,
1130
1169
  has_function=has_function,
1131
1170
  completion=completion,
1171
+ reasoning=reasoning,
1132
1172
  function_args=function_args,
1133
1173
  function_name=function_name,
1134
1174
  )
@@ -1263,6 +1303,7 @@ class OpenAIGPT(LanguageModel):
1263
1303
  tool_deltas: List[Dict[str, Any]] = [],
1264
1304
  has_function: bool = False,
1265
1305
  completion: str = "",
1306
+ reasoning: str = "",
1266
1307
  function_args: str = "",
1267
1308
  function_name: str = "",
1268
1309
  ) -> Tuple[LLMResponse, Dict[str, Any]]:
@@ -1298,7 +1339,12 @@ class OpenAIGPT(LanguageModel):
1298
1339
  tool_deltas,
1299
1340
  )
1300
1341
  completion = completion + "\n" + failed_content
1301
- msg: Dict[str, Any] = dict(message=dict(content=completion))
1342
+ msg: Dict[str, Any] = dict(
1343
+ message=dict(
1344
+ content=completion,
1345
+ reasoning_content=reasoning,
1346
+ ),
1347
+ )
1302
1348
  if len(tool_dicts) > 0:
1303
1349
  msg["message"]["tool_calls"] = tool_dicts
1304
1350
 
@@ -1314,6 +1360,7 @@ class OpenAIGPT(LanguageModel):
1314
1360
  else:
1315
1361
  # non-chat mode has no function_call
1316
1362
  msg = dict(text=completion)
1363
+ # TODO: Ignoring reasoning content for non-chat models
1317
1364
 
1318
1365
  # create an OpenAIResponse object so we can cache it as if it were
1319
1366
  # a non-streaming response
@@ -1324,6 +1371,7 @@ class OpenAIGPT(LanguageModel):
1324
1371
  return (
1325
1372
  LLMResponse(
1326
1373
  message=completion,
1374
+ reasoning=reasoning,
1327
1375
  cached=False,
1328
1376
  # don't allow empty list [] here
1329
1377
  oai_tool_calls=tool_calls or None if len(tool_deltas) > 0 else None,
@@ -1461,6 +1509,7 @@ class OpenAIGPT(LanguageModel):
1461
1509
  )
1462
1510
  args = self._openai_api_call_params(args)
1463
1511
  cached, hashed_key, response = completions_with_backoff(**args)
1512
+ # assume response is an actual response rather than a streaming event
1464
1513
  if not isinstance(response, dict):
1465
1514
  response = response.dict()
1466
1515
  if "message" in response["choices"][0]:
@@ -1534,6 +1583,7 @@ class OpenAIGPT(LanguageModel):
1534
1583
  max_tokens=max_tokens,
1535
1584
  stream=False,
1536
1585
  )
1586
+ # assume response is an actual response rather than a streaming event
1537
1587
  if not isinstance(response, dict):
1538
1588
  response = response.dict()
1539
1589
  if "message" in response["choices"][0]:
@@ -1738,7 +1788,9 @@ class OpenAIGPT(LanguageModel):
1738
1788
  if (
1739
1789
  len(llm_messages) == 1
1740
1790
  and llm_messages[0].role == Role.SYSTEM
1741
- and self.requires_first_user_message()
1791
+ # TODO: we will unconditionally insert a dummy user msg
1792
+ # if the only msg is a system msg.
1793
+ # and self.requires_first_user_message()
1742
1794
  ):
1743
1795
  # some LLMs, notable Gemini as of 12/11/24,
1744
1796
  # require the first message to be from the user,
@@ -1827,6 +1879,7 @@ class OpenAIGPT(LanguageModel):
1827
1879
  "role": "assistant",
1828
1880
  "name": "",
1829
1881
  "content": "\n\nHello there, how may I help you?",
1882
+ "reasoning_content": "Okay, let's see here, hmmm...",
1830
1883
  "function_call": {
1831
1884
  "name": "fun_name",
1832
1885
  "arguments: {
@@ -1845,7 +1898,8 @@ class OpenAIGPT(LanguageModel):
1845
1898
  }
1846
1899
  """
1847
1900
  message = response["choices"][0]["message"]
1848
- msg = message["content"] or ""
1901
+ msg = message.get("content", "")
1902
+ reasoning = message.get("reasoning_content", "")
1849
1903
 
1850
1904
  if message.get("function_call") is None:
1851
1905
  fun_call = None
@@ -1879,6 +1933,7 @@ class OpenAIGPT(LanguageModel):
1879
1933
  msg = msg + "\n" + json.dumps(tool_call_dict)
1880
1934
  return LLMResponse(
1881
1935
  message=msg.strip() if msg is not None else "",
1936
+ reasoning=reasoning.strip() if reasoning is not None else "",
1882
1937
  function_call=fun_call,
1883
1938
  oai_tool_calls=oai_tool_calls or None, # don't allow empty list [] here
1884
1939
  cached=cached,
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import re
2
3
  from enum import Enum
3
4
  from typing import Dict, List, Literal
4
5
 
@@ -250,12 +251,12 @@ class Parser:
250
251
  continue
251
252
 
252
253
  # Find the last period or punctuation mark in the chunk
253
- last_punctuation = max(
254
- chunk_text.rfind("."),
255
- chunk_text.rfind("?"),
256
- chunk_text.rfind("!"),
257
- chunk_text.rfind("\n"),
258
- )
254
+ punctuation_matches = [
255
+ (m.start(), m.group())
256
+ for m in re.finditer(r"(?:[.!?][\s\n]|\n)", chunk_text)
257
+ ]
258
+
259
+ last_punctuation = max([pos for pos, _ in punctuation_matches] + [-1])
259
260
 
260
261
  # If there is a punctuation mark, and the last punctuation index is
261
262
  # after MIN_CHUNK_SIZE_CHARS
@@ -268,7 +269,7 @@ class Parser:
268
269
 
269
270
  # Remove any newline characters and strip any leading or
270
271
  # trailing whitespace
271
- chunk_text_to_append = chunk_text.replace("\n", " ").strip()
272
+ chunk_text_to_append = re.sub(r"\n{2,}", "\n", chunk_text).strip()
272
273
 
273
274
  if len(chunk_text_to_append) > self.config.discard_chunk_chars:
274
275
  # Append the chunk text to the list of chunks
@@ -6,6 +6,8 @@ class Colors(BaseModel):
6
6
  RED: str = "\033[31m"
7
7
  BLUE: str = "\033[34m"
8
8
  GREEN: str = "\033[32m"
9
+ GREEN_DIMMER: str = "\033[38;5;22m" # very dark green
10
+ GREEN_DIM: str = "\033[38;5;28m" # medium-dim green
9
11
  ORANGE: str = "\033[33m" # no standard ANSI color for orange; using yellow
10
12
  CYAN: str = "\033[36m"
11
13
  MAGENTA: str = "\033[35m"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langroid
3
- Version: 0.34.0
3
+ Version: 0.35.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  Author-email: Prasad Chalasani <pchalasani@gmail.com>
6
6
  License: MIT
@@ -287,7 +287,11 @@ teacher_task.run()
287
287
  <details>
288
288
  <summary> <b>Click to expand</b></summary>
289
289
 
290
+ - **Jan 2025:**
291
+ - [0.33.0](https://github.com/langroid/langroid/releases/tag/0.33.3) Move from Poetry to uv!
292
+ - [0.32.0](https://github.com/langroid/langroid/releases/tag/0.32.0) DeepSeek v3 support.
290
293
  - **Dec 2024:**
294
+ - [0.31.0](https://github.com/langroid/langroid/releases/tag/0.31.0) Azure OpenAI Embeddings
291
295
  - [0.30.0](https://github.com/langroid/langroid/releases/tag/0.30.0) Llama-cpp embeddings.
292
296
  - [0.29.0](https://github.com/langroid/langroid/releases/tag/0.29.0) Custom Azure OpenAI Client
293
297
  - [0.28.0](https://github.com/langroid/langroid/releases/tag/0.28.0) `ToolMessage`: `_handler` field to override
@@ -6,7 +6,7 @@ langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,78
6
6
  langroid/agent/base.py,sha256=oThlrYygKDu1-bKjAfygldJ511gMKT8Z0qCrD52DdDM,77834
7
7
  langroid/agent/batch.py,sha256=vi1r5i1-vN80WfqHDSwjEym_KfGsqPGUtwktmiK1nuk,20635
8
8
  langroid/agent/chat_agent.py,sha256=A-7Iiiw7jsoJNlWerljM29BidkiIbjPOQIkGZpZHmt0,82210
9
- langroid/agent/chat_document.py,sha256=xPUMGzR83rn4iAEXIw2jy5LQ6YJ6Y0TiZ78XRQeDnJQ,17778
9
+ langroid/agent/chat_document.py,sha256=xzMtrPbaW-Y-BnF7kuhr2dorsD-D5rMWzfOqJ8HAoo8,17885
10
10
  langroid/agent/openai_assistant.py,sha256=JkAcs02bIrgPNVvUWVR06VCthc5-ulla2QMBzux_q6o,34340
11
11
  langroid/agent/task.py,sha256=XrXUbSoiFasvpIsZPn_cBpdWaTCKljJPRimtLMrSZrs,90347
12
12
  langroid/agent/tool_message.py,sha256=BhjP-_TfQ2tgxuY4Yo_JHLOwwt0mJ4BwjPnREvEY4vk,14744
@@ -14,7 +14,7 @@ langroid/agent/xml_tool_message.py,sha256=6SshYZJKIfi4mkE-gIoSwjkEYekQ8GwcSiCv7a
14
14
  langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  langroid/agent/callbacks/chainlit.py,sha256=RH8qUXaZE5o2WQz3WJQ1SdFtASGlxWCA6_HYz_3meDQ,20822
16
16
  langroid/agent/special/__init__.py,sha256=gik_Xtm_zV7U9s30Mn8UX3Gyuy4jTjQe9zjiE3HWmEo,1273
17
- langroid/agent/special/doc_chat_agent.py,sha256=tI16jVavTSOen9OUoRTl5heDTeTBhWsxW17XU9ZcEko,63563
17
+ langroid/agent/special/doc_chat_agent.py,sha256=8OYJ7IRepdQ9GpoTX_dhw0NkENmTe9iQsJAN6JI-09c,64670
18
18
  langroid/agent/special/lance_doc_chat_agent.py,sha256=s8xoRs0gGaFtDYFUSIRchsgDVbS5Q3C2b2mr3V1Fd-Q,10419
19
19
  langroid/agent/special/lance_tools.py,sha256=qS8x4wi8mrqfbYV2ztFzrcxyhHQ0ZWOc-zkYiH7awj0,2105
20
20
  langroid/agent/special/relevance_extractor_agent.py,sha256=zIx8GUdVo1aGW6ASla0NPQjYYIpmriK_TYMijqAx3F8,4796
@@ -66,10 +66,10 @@ langroid/embedding_models/protoc/embeddings_pb2.pyi,sha256=UkNy7BrNsmQm0vLb3NtGX
66
66
  langroid/embedding_models/protoc/embeddings_pb2_grpc.py,sha256=9dYQqkW3JPyBpSEjeGXTNpSqAkC-6FPtBHyteVob2Y8,2452
67
67
  langroid/language_models/__init__.py,sha256=ps8nhRavCu2-Bv7IQ5hrzody6lzKjHkivJsblDZZIQ8,1020
68
68
  langroid/language_models/azure_openai.py,sha256=zNQzzsERxNestq-hFfQZbvTzK43G2vjRWnTV3ktm1DQ,5845
69
- langroid/language_models/base.py,sha256=MbxfR-10KbhoN0BBkPKqQdEcE7iiPhcFI1zuWvAkvG0,23902
69
+ langroid/language_models/base.py,sha256=avM_RgoTPm1Esr8KSmW-4G0YBSfabeOnTEX3hrT_vM0,24104
70
70
  langroid/language_models/config.py,sha256=9Q8wk5a7RQr8LGMT_0WkpjY8S4ywK06SalVRjXlfCiI,378
71
71
  langroid/language_models/mock_lm.py,sha256=5BgHKDVRWFbUwDT_PFgTZXz9-k8wJSA2e3PZmyDgQ1k,4022
72
- langroid/language_models/openai_gpt.py,sha256=FhpoE75LqWX4BvOo3fgJUPt-QFQDu6eJAuEAv_mTgnc,77352
72
+ langroid/language_models/openai_gpt.py,sha256=1Nru0al-5i2jI4qqwteUt4mYqcBm5Cxdt19wGSnVU7s,79550
73
73
  langroid/language_models/utils.py,sha256=L4_CbihDMTGcsg0TOG1Yd5JFEto46--h7CX_14m89sQ,5016
74
74
  langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
75
75
  langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
@@ -81,7 +81,7 @@ langroid/parsing/code_parser.py,sha256=AOxb3xbYpTBPP3goOm5dKfJdh5hS_2BhLVCEkifWZ
81
81
  langroid/parsing/document_parser.py,sha256=9xUOyrVNBAS9cpCvCptr2XK4Kq47W574i8zzGEoXc3c,24933
82
82
  langroid/parsing/para_sentence_split.py,sha256=AJBzZojP3zpB-_IMiiHismhqcvkrVBQ3ZINoQyx_bE4,2000
83
83
  langroid/parsing/parse_json.py,sha256=aADo38bAHQhC8on4aWZZzVzSDy-dK35vRLZsFI2ewh8,4756
84
- langroid/parsing/parser.py,sha256=bTG5TO2CEwGdLf9979j9_dFntKX5FloGF8vhts6ObU0,11978
84
+ langroid/parsing/parser.py,sha256=N0jr1Zl_f_rx-8YMmSQftPHquqSQfec-3s7JAhhEe6I,12032
85
85
  langroid/parsing/repo_loader.py,sha256=3GjvPJS6Vf5L6gV2zOU8s-Tf1oq_fZm-IB_RL_7CTsY,29373
86
86
  langroid/parsing/routing.py,sha256=-FcnlqldzL4ZoxuDwXjQPNHgBe9F9-F4R6q7b_z9CvI,1232
87
87
  langroid/parsing/search.py,sha256=0i_r0ESb5HEQfagA2g7_uMQyxYPADWVbdcN9ixZhS4E,8992
@@ -99,7 +99,7 @@ langroid/pydantic_v1/__init__.py,sha256=HxPGVERapVueRUORgSpj2JX_vTZxVlVbWvhpQlpj
99
99
  langroid/pydantic_v1/main.py,sha256=p_k7kDY9eDrsA5dxNNqXusKLgx7mS_icGnS7fu4goqY,147
100
100
  langroid/utils/__init__.py,sha256=Sruos2tB4G7Tn0vlblvYlX9PEGR0plI2uE0PJ4d_EC4,353
101
101
  langroid/utils/configuration.py,sha256=V3RS8OP7AC0_bDKczxfortD0F5H3cnsZL0ulKBxuoHU,3213
102
- langroid/utils/constants.py,sha256=vKIdkAJwyPT-bRA5MDPiOl7-EppBRmewRBIOcdXi4I4,959
102
+ langroid/utils/constants.py,sha256=CK09kda9bNDEhnwClq7ZTWZOh38guJlfcZ5hKUS1Ijo,1075
103
103
  langroid/utils/git_utils.py,sha256=WnflJ3R3owhlD0LNdSJakcKhExcEehE1UW5jYVQl8JY,7955
104
104
  langroid/utils/globals.py,sha256=Az9dOFqR6n9CoTYSqa2kLikQWS0oCQ9DFQIQAnG-2q8,1355
105
105
  langroid/utils/logging.py,sha256=mwxHimq1wtVQ64PvDyfJJ7Upj-rjHLNHgx8EC2wClvo,4024
@@ -121,7 +121,7 @@ langroid/vector_store/lancedb.py,sha256=b3_vWkTjG8mweZ7ZNlUD-NjmQP_rLBZfyKWcxt2v
121
121
  langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3HmhHQICXLs,11663
122
122
  langroid/vector_store/momento.py,sha256=UNHGT6jXuQtqY9f6MdqGU14bVnS0zHgIJUa30ULpUJo,10474
123
123
  langroid/vector_store/qdrantdb.py,sha256=HRLCt-FG8y4718omwpFaQZnWeYxPj0XCwS4tjokI1sU,18116
124
- langroid-0.34.0.dist-info/METADATA,sha256=fo7ULfjnWFED6Cag8aUFjOaPqEatQKBXEz-Z_rFyHnk,59015
125
- langroid-0.34.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
126
- langroid-0.34.0.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
127
- langroid-0.34.0.dist-info/RECORD,,
124
+ langroid-0.35.0.dist-info/METADATA,sha256=57TZcMnBYqUH2CiqMsjLqJA2oclSLKY4igiXFlZwx_Y,59313
125
+ langroid-0.35.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
126
+ langroid-0.35.0.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
127
+ langroid-0.35.0.dist-info/RECORD,,