langroid 0.1.233__py3-none-any.whl → 0.1.235__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.
langroid/__init__.py CHANGED
@@ -27,6 +27,7 @@ from .agent.batch import (
27
27
  )
28
28
 
29
29
  from .agent.chat_document import (
30
+ StatusCode,
30
31
  ChatDocument,
31
32
  ChatDocMetaData,
32
33
  )
@@ -77,6 +78,7 @@ __all__ = [
77
78
  "AgentConfig",
78
79
  "ChatAgent",
79
80
  "ChatAgentConfig",
81
+ "StatusCode",
80
82
  "ChatDocument",
81
83
  "ChatDocMetaData",
82
84
  "Task",
langroid/agent/batch.py CHANGED
@@ -53,6 +53,7 @@ def run_batch_task_gen(
53
53
  message (Optional[str]): optionally overrides the console status messages
54
54
  handle_exceptions: bool: Whether to replace exceptions with outputs of None
55
55
  max_cost: float: maximum cost to run the task (default 0.0 for unlimited)
56
+ max_tokens: int: maximum token usage (in and out) (default 0 for unlimited)
56
57
 
57
58
 
58
59
  Returns:
@@ -1,4 +1,5 @@
1
1
  import json
2
+ from enum import Enum
2
3
  from typing import List, Optional, Union
3
4
 
4
5
  from pydantic import BaseModel, Extra
@@ -23,6 +24,23 @@ class ChatDocAttachment(BaseModel):
23
24
  extra = Extra.allow
24
25
 
25
26
 
27
+ class StatusCode(str, Enum):
28
+ """Codes meant to be returned by task.run(). Some are not used yet."""
29
+
30
+ OK = "OK"
31
+ ERROR = "ERROR"
32
+ DONE = "DONE"
33
+ STALLED = "STALLED"
34
+ INF_LOOP = "INF_LOOP"
35
+ KILL = "KILL"
36
+ MAX_TURNS = "MAX_TURNS"
37
+ MAX_COST = "MAX_COST"
38
+ MAX_TOKENS = "MAX_TOKENS"
39
+ TIMEOUT = "TIMEOUT"
40
+ NO_ANSWER = "NO_ANSWER"
41
+ USER_QUIT = "USER_QUIT"
42
+
43
+
26
44
  class ChatDocMetaData(DocMetaData):
27
45
  parent: Optional["ChatDocument"] = None
28
46
  sender: Entity
@@ -35,6 +53,7 @@ class ChatDocMetaData(DocMetaData):
35
53
  usage: Optional[LLMTokenUsage]
36
54
  cached: bool = False
37
55
  displayed: bool = False
56
+ status: Optional[StatusCode] = None
38
57
 
39
58
 
40
59
  class ChatDocLoggerFields(BaseModel):
@@ -14,7 +14,7 @@ from .table_chat_agent import (
14
14
  dataframe_summary,
15
15
  TableChatAgent,
16
16
  TableChatAgentConfig,
17
- RunCodeTool,
17
+ PandasEvalTool,
18
18
  )
19
19
  from . import sql
20
20
  from . import relevance_extractor_agent
@@ -38,7 +38,7 @@ __all__ = [
38
38
  "dataframe_summary",
39
39
  "TableChatAgent",
40
40
  "TableChatAgentConfig",
41
- "RunCodeTool",
41
+ "PandasEvalTool",
42
42
  "sql",
43
43
  "relevance_extractor_agent",
44
44
  "doc_chat_agent",
@@ -2,10 +2,11 @@
2
2
  Agent that supports asking queries about a tabular dataset, internally
3
3
  represented as a Pandas dataframe. The `TableChatAgent` is configured with a
4
4
  dataset, which can be a Pandas df, file or URL. The delimiter/separator
5
- is auto-detected. In response to a user query, the Agent's LLM generates Pandas
6
- code to answer the query. The code is passed via the `run_code` tool/function-call,
7
- which is handled by the Agent's `run_code` method. This method executes/evaluates
8
- the code and returns the result as a string.
5
+ is auto-detected. In response to a user query, the Agent's LLM generates a Pandas
6
+ expression (involving a dataframe `df`) to answer the query.
7
+ The expression is passed via the `pandas_eval` tool/function-call,
8
+ which is handled by the Agent's `pandas_eval` method. This method evaluates
9
+ the expression and returns the result as a string.
9
10
  """
10
11
 
11
12
  import io
@@ -35,25 +36,26 @@ DEFAULT_TABLE_CHAT_SYSTEM_MESSAGE = f"""
35
36
  You are a savvy data scientist, with expertise in analyzing tabular datasets,
36
37
  using Python and the Pandas library for dataframe manipulation.
37
38
  Since you do not have access to the dataframe 'df', you
38
- will need to use the `run_code` tool/function-call to answer my questions.
39
+ will need to use the `pandas_eval` tool/function-call to answer my questions.
39
40
  Here is a summary of the dataframe:
40
41
  {{summary}}
41
42
  Do not assume any columns other than those shown.
42
- In the code you submit to the `run_code` tool/function,
43
- do not forget to include any necessary imports, such as `import pandas as pd`.
44
- Sometimes you may not be able to answer the question in a single call to `run_code`,
45
- so you can use a series of calls to `run_code` to build up the answer.
43
+ In the expression you submit to the `pandas_eval` tool/function,
44
+ you are allowed to use the variable 'df' to refer to the dataframe.
45
+
46
+ Sometimes you may not be able to answer the question in a single call to `pandas_eval`,
47
+ so you can use a series of calls to `pandas_eval` to build up the answer.
46
48
  For example you may first want to know something about the possible values in a column.
47
49
 
48
50
  If you receive a null or other unexpected result, see if you have made an assumption
49
- in your code, and try another way, or use `run_code` to explore the dataframe
51
+ in your code, and try another way, or use `pandas_eval` to explore the dataframe
50
52
  before submitting your final code.
51
53
 
52
54
  Once you have the answer to the question, possibly after a few steps,
53
55
  say {DONE} and show me the answer. If you receive an error message,
54
- try using the `run_code` tool/function again with the corrected code.
56
+ try using the `pandas_eval` tool/function again with the corrected code.
55
57
 
56
- VERY IMPORTANT: When using the `run_code` tool/function, DO NOT EXPLAIN ANYTHING,
58
+ VERY IMPORTANT: When using the `pandas_eval` tool/function, DO NOT EXPLAIN ANYTHING,
57
59
  SIMPLY USE THE TOOL, with the CODE.
58
60
  Start by asking me what I want to know about the data.
59
61
  """
@@ -123,22 +125,22 @@ class TableChatAgentConfig(ChatAgentConfig):
123
125
  )
124
126
 
125
127
 
126
- class RunCodeTool(ToolMessage):
127
- """Tool/function to run code on a dataframe named `df`"""
128
+ class PandasEvalTool(ToolMessage):
129
+ """Tool/function to evaluate a pandas expression involving a dataframe `df`"""
128
130
 
129
- request: str = "run_code"
131
+ request: str = "pandas_eval"
130
132
  purpose: str = """
131
- To run <code> on the dataframe 'df' and
133
+ To eval a pandas <expression> on the dataframe 'df' and
132
134
  return the results to answer a question.
133
- IMPORTANT: ALL the code should be in the <code> field.
135
+ IMPORTANT: the <expression> field should be a valid pandas expression.
134
136
  """
135
- code: str
137
+ expression: str
136
138
 
137
139
  @classmethod
138
140
  def examples(cls) -> List["ToolMessage"]:
139
141
  return [
140
- cls(code="df.head()"),
141
- cls(code="df[(df['gender'] == 'Male')]['income'].mean()"),
142
+ cls(expression="df.head()"),
143
+ cls(expression="df[(df['gender'] == 'Male')]['income'].mean()"),
142
144
  ]
143
145
 
144
146
 
@@ -147,7 +149,7 @@ class TableChatAgent(ChatAgent):
147
149
  Agent for chatting with a collection of documents.
148
150
  """
149
151
 
150
- sent_code: bool = False
152
+ sent_expression: bool = False
151
153
 
152
154
  def __init__(self, config: TableChatAgentConfig):
153
155
  if isinstance(config.data, pd.DataFrame):
@@ -170,8 +172,8 @@ class TableChatAgent(ChatAgent):
170
172
  {self.df.columns}
171
173
  """
172
174
  )
173
- # enable the agent to use and handle the RunCodeTool
174
- self.enable_message(RunCodeTool)
175
+ # enable the agent to use and handle the PandasEvalTool
176
+ self.enable_message(PandasEvalTool)
175
177
 
176
178
  def user_response(
177
179
  self,
@@ -179,44 +181,31 @@ class TableChatAgent(ChatAgent):
179
181
  ) -> Optional[ChatDocument]:
180
182
  response = super().user_response(msg)
181
183
  if response is not None and response.content != "":
182
- self.sent_code = False
184
+ self.sent_expression = False
183
185
  return response
184
186
 
185
- def run_code(self, msg: RunCodeTool) -> str:
187
+ def pandas_eval(self, msg: PandasEvalTool) -> str:
186
188
  """
187
- Handle a RunCodeTool message by running the code and returning the result.
189
+ Handle a PandasEvalTool message by evaluating the `expression` field
190
+ and returning the result.
188
191
  Args:
189
- msg (RunCodeTool): The tool-message to handle.
192
+ msg (PandasEvalTool): The tool-message to handle.
190
193
 
191
194
  Returns:
192
195
  str: The result of running the code along with any print output.
193
196
  """
194
- self.sent_code = True
195
- code = msg.code
196
- # Create a dictionary that maps 'df' to the actual DataFrame
197
+ self.sent_expression = True
198
+ exprn = msg.expression
197
199
  local_vars = {"df": self.df}
198
-
199
200
  # Create a string-based I/O stream
200
201
  code_out = io.StringIO()
201
202
 
202
203
  # Temporarily redirect standard output to our string-based I/O stream
203
204
  sys.stdout = code_out
204
205
 
205
- # Split the code into lines
206
- lines = code.strip().split("\n")
207
-
208
- lines = [
209
- "import pandas as pd",
210
- "import numpy as np",
211
- ] + lines
212
-
213
- # Run all lines as statements except for the last one
214
- for line in lines[:-1]:
215
- exec(line, {}, local_vars)
216
-
217
206
  # Evaluate the last line and get the result
218
207
  try:
219
- eval_result = pd.eval(lines[-1], local_dict=local_vars)
208
+ eval_result = pd.eval(exprn, local_dict=local_vars)
220
209
  except Exception as e:
221
210
  eval_result = f"ERROR: {type(e)}: {e}"
222
211
 
@@ -242,15 +231,15 @@ class TableChatAgent(ChatAgent):
242
231
  def handle_message_fallback(
243
232
  self, msg: str | ChatDocument
244
233
  ) -> str | ChatDocument | None:
245
- """Handle scenario where LLM forgets to say DONE or forgets to use run_code"""
234
+ """Handle scenario where LLM forgets to say DONE or
235
+ forgets to use pandas_eval"""
246
236
  if isinstance(msg, ChatDocument) and msg.metadata.sender == lr.Entity.LLM:
247
- if self.sent_code:
237
+ if self.sent_expression:
248
238
  return DONE
249
239
  else:
250
240
  return """
251
- You forgot to use the `run_code` tool/function to find the answer.
252
- Try again using the `run_code` tool/function.
253
- Remember that ALL your code, including imports,
254
- should be in the `code` field.
241
+ You forgot to use the `pandas_eval` tool/function
242
+ to find the answer.
243
+ Try again using the `pandas_eval` tool/function.
255
244
  """
256
245
  return None
langroid/agent/task.py CHANGED
@@ -27,11 +27,20 @@ from langroid.agent.chat_document import (
27
27
  ChatDocLoggerFields,
28
28
  ChatDocMetaData,
29
29
  ChatDocument,
30
+ StatusCode,
30
31
  )
32
+ from langroid.cachedb.redis_cachedb import RedisCache, RedisCacheConfig
31
33
  from langroid.mytypes import Entity
32
34
  from langroid.parsing.parse_json import extract_top_level_json
33
35
  from langroid.utils.configuration import settings
34
- from langroid.utils.constants import DONE, NO_ANSWER, PASS, PASS_TO, SEND_TO, USER_QUIT
36
+ from langroid.utils.constants import (
37
+ DONE,
38
+ NO_ANSWER,
39
+ PASS,
40
+ PASS_TO,
41
+ SEND_TO,
42
+ USER_QUIT_STRINGS,
43
+ )
35
44
  from langroid.utils.logging import RichFileLogger, setup_file_logger
36
45
 
37
46
  logger = logging.getLogger(__name__)
@@ -73,6 +82,8 @@ class Task:
73
82
  the value of `result()`, which is the final result of the task.
74
83
  """
75
84
 
85
+ # class variable called `cache` that is a RedisCache object
86
+ cache: RedisCache = RedisCache(RedisCacheConfig(fake=False))
76
87
  def __init__(
77
88
  self,
78
89
  agent: Optional[Agent] = None,
@@ -141,7 +152,6 @@ class Task:
141
152
  """
142
153
  if agent is None:
143
154
  agent = ChatAgent()
144
-
145
155
  self.callbacks = SimpleNamespace(
146
156
  show_subtask_response=noop_fn,
147
157
  set_parent_agent=noop_fn,
@@ -172,6 +182,7 @@ class Task:
172
182
  agent.set_user_message(user_message)
173
183
  self.max_cost: float = 0
174
184
  self.max_tokens: int = 0
185
+ self.session_id: str = ""
175
186
  self.logger: None | RichFileLogger = None
176
187
  self.tsv_logger: None | logging.Logger = None
177
188
  self.color_log: bool = False if settings.notebook else True
@@ -285,6 +296,54 @@ class Task:
285
296
  def __str__(self) -> str:
286
297
  return f"{self.name}"
287
298
 
299
+ def _cache_session_store(self, key: str, value: str) -> None:
300
+ """
301
+ Cache a key-value pair for the current session.
302
+ E.g. key = "kill", value = "1"
303
+ """
304
+ try:
305
+ self.cache.store(f"{self.session_id}:{key}", value)
306
+ except Exception as e:
307
+ logging.error(f"Error in Task._cache_session_store: {e}")
308
+
309
+ def _cache_session_lookup(self, key: str) -> Dict[str, Any] | str | None:
310
+ """
311
+ Retrieve a value from the cache for the current session.
312
+ """
313
+ session_id_key = f"{self.session_id}:{key}"
314
+ try:
315
+ cached_val = self.cache.retrieve(session_id_key)
316
+ except Exception as e:
317
+ logging.error(f"Error in Task._cache_session_lookup: {e}")
318
+ return None
319
+ return cached_val
320
+
321
+ def _is_kill(self) -> bool:
322
+ """
323
+ Check if the current session is killed.
324
+ """
325
+ return self._cache_session_lookup("kill") == "1"
326
+
327
+ def _set_alive(self) -> None:
328
+ """
329
+ Initialize the kill status of the current session.
330
+ """
331
+ self._cache_session_store("kill", "0")
332
+
333
+ @classmethod
334
+ def kill_session(cls, session_id=""):
335
+ """
336
+ Kill the current session.
337
+ """
338
+ session_id_kill_key = f"{session_id}:kill"
339
+ cls.cache.store(session_id_kill_key, "1")
340
+
341
+ def kill(self) -> None:
342
+ """
343
+ Kill the task run associated with the current session.
344
+ """
345
+ self._cache_session_store("kill", "1")
346
+
288
347
  @property
289
348
  def _level(self) -> int:
290
349
  if self.caller is None:
@@ -378,6 +437,7 @@ class Task:
378
437
  caller: None | Task = None,
379
438
  max_cost: float = 0,
380
439
  max_tokens: int = 0,
440
+ session_id: str = "",
381
441
  ) -> Optional[ChatDocument]:
382
442
  """Synchronous version of `run_async()`.
383
443
  See `run_async()` for details."""
@@ -385,6 +445,9 @@ class Task:
385
445
  self.n_stalled_steps = 0
386
446
  self.max_cost = max_cost
387
447
  self.max_tokens = max_tokens
448
+ self.session_id = session_id
449
+ self._set_alive()
450
+
388
451
  assert (
389
452
  msg is None or isinstance(msg, str) or isinstance(msg, ChatDocument)
390
453
  ), f"msg arg in Task.run() must be None, str, or ChatDocument, not {type(msg)}"
@@ -406,15 +469,19 @@ class Task:
406
469
  i = 0
407
470
  while True:
408
471
  self.step()
409
- if self.done():
472
+ done, status = self.done()
473
+ if done:
410
474
  if self._level == 0 and not settings.quiet:
411
475
  print("[magenta]Bye, hope this was useful!")
412
476
  break
413
477
  i += 1
414
478
  if turns > 0 and i >= turns:
479
+ status = StatusCode.MAX_TURNS
415
480
  break
416
481
 
417
482
  final_result = self.result()
483
+ if final_result is not None:
484
+ final_result.metadata.status = status
418
485
  self._post_run_loop()
419
486
  return final_result
420
487
 
@@ -425,6 +492,7 @@ class Task:
425
492
  caller: None | Task = None,
426
493
  max_cost: float = 0,
427
494
  max_tokens: int = 0,
495
+ session_id: str = "",
428
496
  ) -> Optional[ChatDocument]:
429
497
  """
430
498
  Loop over `step()` until task is considered done or `turns` is reached.
@@ -443,6 +511,7 @@ class Task:
443
511
  caller (Task|None): the calling task, if any
444
512
  max_cost (float): max cost allowed for the task (default 0 -> no limit)
445
513
  max_tokens (int): max tokens allowed for the task (default 0 -> no limit)
514
+ session_id (str): session id for the task
446
515
 
447
516
  Returns:
448
517
  Optional[ChatDocument]: valid result of the task.
@@ -456,6 +525,9 @@ class Task:
456
525
  self.n_stalled_steps = 0
457
526
  self.max_cost = max_cost
458
527
  self.max_tokens = max_tokens
528
+ self.session_id = session_id
529
+ self._set_alive()
530
+
459
531
  if (
460
532
  isinstance(msg, ChatDocument)
461
533
  and msg.metadata.recipient != ""
@@ -473,15 +545,19 @@ class Task:
473
545
  i = 0
474
546
  while True:
475
547
  await self.step_async()
476
- if self.done():
548
+ done, status = self.done()
549
+ if done:
477
550
  if self._level == 0 and not settings.quiet:
478
551
  print("[magenta]Bye, hope this was useful!")
479
552
  break
480
553
  i += 1
481
554
  if turns > 0 and i >= turns:
555
+ status = StatusCode.MAX_TURNS
482
556
  break
483
557
 
484
558
  final_result = self.result()
559
+ if final_result is not None:
560
+ final_result.metadata.status = status
485
561
  self._post_run_loop()
486
562
  return final_result
487
563
 
@@ -942,6 +1018,7 @@ class Task:
942
1018
  recipient = result_msg.metadata.recipient if result_msg else None
943
1019
  responder = result_msg.metadata.parent_responder if result_msg else None
944
1020
  tool_ids = result_msg.metadata.tool_ids if result_msg else []
1021
+ status = result_msg.metadata.status if result_msg else None
945
1022
 
946
1023
  # regardless of which entity actually produced the result,
947
1024
  # when we return the result, we set entity to USER
@@ -954,6 +1031,7 @@ class Task:
954
1031
  source=Entity.USER,
955
1032
  sender=Entity.USER,
956
1033
  block=block,
1034
+ status=status,
957
1035
  parent_responder=responder,
958
1036
  sender_name=self.name,
959
1037
  recipient=recipient,
@@ -1036,7 +1114,7 @@ class Task:
1036
1114
 
1037
1115
  def done(
1038
1116
  self, result: ChatDocument | None = None, r: Responder | None = None
1039
- ) -> bool:
1117
+ ) -> Tuple[bool, StatusCode]:
1040
1118
  """
1041
1119
  Check if task is done. This is the default behavior.
1042
1120
  Derived classes can override this.
@@ -1046,26 +1124,29 @@ class Task:
1046
1124
  Not used here, but could be used by derived classes.
1047
1125
  Returns:
1048
1126
  bool: True if task is done, False otherwise
1127
+ StatusCode: status code indicating why task is done
1049
1128
  """
1129
+ if self._is_kill():
1130
+ return (True, StatusCode.KILL)
1050
1131
  result = result or self.pending_message
1051
1132
  user_quit = (
1052
1133
  result is not None
1053
- and result.content in USER_QUIT
1134
+ and result.content in USER_QUIT_STRINGS
1054
1135
  and result.metadata.sender == Entity.USER
1055
1136
  )
1056
1137
  if self._level == 0 and self.only_user_quits_root:
1057
1138
  # for top-level task, only user can quit out
1058
- return user_quit
1139
+ return (user_quit, StatusCode.USER_QUIT if user_quit else StatusCode.OK)
1059
1140
 
1060
1141
  if self.is_done:
1061
- return True
1142
+ return (True, StatusCode.DONE)
1062
1143
 
1063
1144
  if self.n_stalled_steps >= self.max_stalled_steps:
1064
1145
  # we are stuck, so bail to avoid infinite loop
1065
1146
  logger.warning(
1066
1147
  f"Task {self.name} stuck for {self.max_stalled_steps} steps; exiting."
1067
1148
  )
1068
- return True
1149
+ return (True, StatusCode.STALLED)
1069
1150
 
1070
1151
  if self.max_cost > 0 and self.agent.llm is not None:
1071
1152
  try:
@@ -1073,7 +1154,7 @@ class Task:
1073
1154
  logger.warning(
1074
1155
  f"Task {self.name} cost exceeded {self.max_cost}; exiting."
1075
1156
  )
1076
- return True
1157
+ return (True, StatusCode.MAX_COST)
1077
1158
  except Exception:
1078
1159
  pass
1079
1160
 
@@ -1083,10 +1164,10 @@ class Task:
1083
1164
  logger.warning(
1084
1165
  f"Task {self.name} uses > {self.max_tokens} tokens; exiting."
1085
1166
  )
1086
- return True
1167
+ return (True, StatusCode.MAX_TOKENS)
1087
1168
  except Exception:
1088
1169
  pass
1089
- return (
1170
+ final = (
1090
1171
  # no valid response from any entity/agent in current turn
1091
1172
  result is None
1092
1173
  # An entity decided task is done
@@ -1103,6 +1184,7 @@ class Task:
1103
1184
  # )
1104
1185
  or user_quit
1105
1186
  )
1187
+ return (final, StatusCode.OK)
1106
1188
 
1107
1189
  def valid(
1108
1190
  self,
@@ -1120,7 +1202,7 @@ class Task:
1120
1202
 
1121
1203
  # if task would be considered done given responder r's `result`,
1122
1204
  # then consider the result valid.
1123
- if result is not None and self.done(result, r):
1205
+ if result is not None and self.done(result, r)[0]:
1124
1206
  return True
1125
1207
  return (
1126
1208
  result is not None
@@ -109,7 +109,7 @@ class RedisCache(CacheDB):
109
109
  key (str): The key to retrieve the value for.
110
110
 
111
111
  Returns:
112
- dict: The value associated with the key.
112
+ dict|str|None: The value associated with the key.
113
113
  """
114
114
  with self.redis_client() as client: # type: ignore
115
115
  try:
@@ -13,7 +13,7 @@ class Colors(BaseModel):
13
13
  RESET: str = "\033[0m"
14
14
 
15
15
 
16
- USER_QUIT = ["q", "x", "quit", "exit", "bye"]
16
+ USER_QUIT_STRINGS = ["q", "x", "quit", "exit", "bye"]
17
17
  NO_ANSWER = "DO-NOT-KNOW"
18
18
  DONE = "DONE"
19
19
  PASS = "__PASS__"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.1.233
3
+ Version: 0.1.235
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -1,15 +1,15 @@
1
- langroid/__init__.py,sha256=qgY-OqzYSWOc6EytQJN9sH2PwDp1UIzP9lXhrYH6aLU,1645
1
+ langroid/__init__.py,sha256=zsYpGiAUsvyzZzjm964NUamsJImrXSJPVGz9a2jE_uY,1679
2
2
  langroid/agent/__init__.py,sha256=_D8dxnfdr92ch1CIrUkKjrB5HVvsQdn62b1Fb2kBxV8,785
3
3
  langroid/agent/base.py,sha256=jyGFmojrFuOy81lUkNsJlR6mLIOY6kOD20P9dhEcEuw,35059
4
- langroid/agent/batch.py,sha256=SyvUwKetPH_4JKgTnV0bgXS7eD_qfFl9cq06lnill4o,9956
4
+ langroid/agent/batch.py,sha256=feRA_yRG768ElOQjrKEefcRv6Aefd_yY7qktuYUQDwc,10040
5
5
  langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  langroid/agent/callbacks/chainlit.py,sha256=aYuJ8M4VDHr5oymoXL2bpThM7p6P9L45fgJf3MLdkWo,20997
7
7
  langroid/agent/chat_agent.py,sha256=X5uVMm9qdw3j-FRf4hbN8k8ByaSdtQCTuU8olKE0sbs,38750
8
- langroid/agent/chat_document.py,sha256=PL8iA1ZYjXNFVa3kMO8T4sbbM3rzHWpRAY6PN_7n5LQ,7969
8
+ langroid/agent/chat_document.py,sha256=NGr5FEWasPUQZ7cJnqrkVYYTi5fOqplSoCU-z5tTONA,8422
9
9
  langroid/agent/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  langroid/agent/junk,sha256=LxfuuW7Cijsg0szAzT81OjWWv1PMNI-6w_-DspVIO2s,339
11
11
  langroid/agent/openai_assistant.py,sha256=xWSDR4SyMcZhCUkgaM4-mu77rbEDF_xpt7N8m8CkiA4,32962
12
- langroid/agent/special/__init__.py,sha256=XPE076zD-roskxNBn-A1hnh4AHoMiQN9gk1UDjPaBaU,1201
12
+ langroid/agent/special/__init__.py,sha256=NG0JkB5y4K0bgnd9Q9UIvFExun3uTfVOWEVLVymff1M,1207
13
13
  langroid/agent/special/doc_chat_agent.py,sha256=LwWNb_1s5n9rOk9OpOFPuuY1VnVX5DjzQmPwBanKRrM,53763
14
14
  langroid/agent/special/lance_doc_chat_agent.py,sha256=USp0U3eTaJzwF_3bdqE7CedSLbaqAi2tm-VzygcyLaA,10175
15
15
  langroid/agent/special/lance_rag/__init__.py,sha256=QTbs0IVE2ZgDg8JJy1zN97rUUg4uEPH7SLGctFNumk4,174
@@ -31,8 +31,8 @@ langroid/agent/special/sql/utils/description_extractors.py,sha256=RZ2R3DmASxB1ij
31
31
  langroid/agent/special/sql/utils/populate_metadata.py,sha256=x2OMKfmIBnJESBG3qKt6gvr3H3L4ZQcoxHfNdWfHjZs,2987
32
32
  langroid/agent/special/sql/utils/system_message.py,sha256=qKLHkvQWRQodTtPLPxr1GSLUYUFASZU8x-ybV67cB68,1885
33
33
  langroid/agent/special/sql/utils/tools.py,sha256=6uB2424SLtmapui9ggcEr0ZTiB6_dL1-JRGgN8RK9Js,1332
34
- langroid/agent/special/table_chat_agent.py,sha256=-Qtqr2FP8VcyYcA-Pzqa9ucSl1-nXudbNsv_qakSSco,9041
35
- langroid/agent/task.py,sha256=jUeKRreYvs_6OlOqVxqfYWQHtvDZViUDtx5wl_b9cyY,51160
34
+ langroid/agent/special/table_chat_agent.py,sha256=coEvEWL9UJJSeDu8JcOxR4qCyzH7HuTdre7-3pMfGjo,8785
35
+ langroid/agent/task.py,sha256=kySe76a4M0YT4Fg7kXdvklUfBEG-RXKwn7o-aWKDuao,53986
36
36
  langroid/agent/tool_message.py,sha256=2kPsQUwi3ZzINTUNj10huKnZLjLp5SXmefacTHx8QDc,8304
37
37
  langroid/agent/tools/__init__.py,sha256=q-maq3k2BXhPAU99G0H6-j_ozoRvx15I1RFpPVicQIU,304
38
38
  langroid/agent/tools/duckduckgo_search_tool.py,sha256=mLGhlgs6pwbYZIwrOs9shfh1dMBVT4DtkR29pYL3cCQ,1900
@@ -47,7 +47,7 @@ langroid/agent_config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
47
  langroid/cachedb/__init__.py,sha256=ygx42MS7fvh2UwRMjukTk3dWBkzv_rACebTBRYa_MkU,148
48
48
  langroid/cachedb/base.py,sha256=tdIZmdDdDMW-wVkNQdi4vMQCHP718l9JM6cDhL6odf4,1229
49
49
  langroid/cachedb/momento_cachedb.py,sha256=IbaYG7HgG-G18GlWsYVnLv0r2e2S48z6sl8OlJOGUfc,2998
50
- langroid/cachedb/redis_cachedb.py,sha256=uEjxephnxaL8OqPGDYZnM__fpcTsLb0WTNS_AFimkvA,4984
50
+ langroid/cachedb/redis_cachedb.py,sha256=5WrwgareXGboZeaCLkJ8MarqRMrrXl4_8o8aDrdrOCE,4993
51
51
  langroid/embedding_models/__init__.py,sha256=AJg2668ytmUyqYP0SGw-ZKz2ITi4YK7IAv2lfCjFfOg,714
52
52
  langroid/embedding_models/base.py,sha256=xY9QF01ilsMvaNH4JMDvkZgXY59AeYR4VAykgNd6Flg,1818
53
53
  langroid/embedding_models/clustering.py,sha256=tZWElUqXl9Etqla0FAa7og96iDKgjqWjucZR_Egtp-A,6684
@@ -98,7 +98,7 @@ langroid/utils/__init__.py,sha256=ARx5To4Hsv1K5QAzK4uUqdEoB_iq5HK797vae1AcMBI,30
98
98
  langroid/utils/algorithms/__init__.py,sha256=WylYoZymA0fnzpB4vrsH_0n7WsoLhmuZq8qxsOCjUpM,41
99
99
  langroid/utils/algorithms/graph.py,sha256=JbdpPnUOhw4-D6O7ou101JLA3xPCD0Lr3qaPoFCaRfo,2866
100
100
  langroid/utils/configuration.py,sha256=TiDZrQVeEthMFA4QY_HTgQaDCJwS4I5S-aR_taOdc00,3201
101
- langroid/utils/constants.py,sha256=_t4eZ2KamgqOaOH1PKXq1_BzYRTA8qZ1NJ4kHXJYzlI,555
101
+ langroid/utils/constants.py,sha256=Y_8p7CyLF5b3xsEV5O3wuutLHQCtegsaxWgr8yNTlIE,563
102
102
  langroid/utils/docker.py,sha256=kJQOLTgM0x9j9pgIIqp0dZNZCTvoUDhp6i8tYBq1Jr0,1105
103
103
  langroid/utils/globals.py,sha256=VkTHhlqSz86oOPq65sjul0XU8I52UNaFC5vwybMQ74w,1343
104
104
  langroid/utils/llms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -120,7 +120,7 @@ langroid/vector_store/meilisearch.py,sha256=d2huA9P-NoYRuAQ9ZeXJmMKr7ry8u90RUSR2
120
120
  langroid/vector_store/momento.py,sha256=9cui31TTrILid2KIzUpBkN2Ey3g_CZWOQVdaFsA4Ors,10045
121
121
  langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
122
122
  langroid/vector_store/qdrantdb.py,sha256=foKRxRv0BBony6S4Vt0Vav9Rn9HMxZvcIh1cE7nosFE,13524
123
- langroid-0.1.233.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
124
- langroid-0.1.233.dist-info/METADATA,sha256=vxJscoG8qWCn8tfLfCDhVHiomACst_EJcldbP3PNw_M,47863
125
- langroid-0.1.233.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
126
- langroid-0.1.233.dist-info/RECORD,,
123
+ langroid-0.1.235.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
124
+ langroid-0.1.235.dist-info/METADATA,sha256=2wohvUQdJu1EEAoNtT8tg8eOPgk6EeN3mxsSvOB0Zw4,47863
125
+ langroid-0.1.235.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
126
+ langroid-0.1.235.dist-info/RECORD,,