langroid 0.1.231__py3-none-any.whl → 0.1.234__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/agent/batch.py +8 -1
- langroid/agent/special/__init__.py +2 -2
- langroid/agent/special/doc_chat_agent.py +10 -3
- langroid/agent/special/table_chat_agent.py +39 -49
- langroid/agent/task.py +20 -2
- {langroid-0.1.231.dist-info → langroid-0.1.234.dist-info}/METADATA +1 -1
- {langroid-0.1.231.dist-info → langroid-0.1.234.dist-info}/RECORD +9 -9
- {langroid-0.1.231.dist-info → langroid-0.1.234.dist-info}/LICENSE +0 -0
- {langroid-0.1.231.dist-info → langroid-0.1.234.dist-info}/WHEEL +0 -0
langroid/agent/batch.py
CHANGED
@@ -32,6 +32,7 @@ def run_batch_task_gen(
|
|
32
32
|
message: Optional[str] = None,
|
33
33
|
handle_exceptions: bool = False,
|
34
34
|
max_cost: float = 0.0,
|
35
|
+
max_tokens: int = 0,
|
35
36
|
) -> list[U]:
|
36
37
|
"""
|
37
38
|
Generate and run copies of a task async/concurrently one per item in `items` list.
|
@@ -53,6 +54,7 @@ def run_batch_task_gen(
|
|
53
54
|
handle_exceptions: bool: Whether to replace exceptions with outputs of None
|
54
55
|
max_cost: float: maximum cost to run the task (default 0.0 for unlimited)
|
55
56
|
|
57
|
+
|
56
58
|
Returns:
|
57
59
|
list[Any]: list of final results
|
58
60
|
"""
|
@@ -64,7 +66,9 @@ def run_batch_task_gen(
|
|
64
66
|
task_i.agent.llm.set_stream(False)
|
65
67
|
task_i.agent.config.show_stats = False
|
66
68
|
|
67
|
-
result = await task_i.run_async(
|
69
|
+
result = await task_i.run_async(
|
70
|
+
input, turns=turns, max_cost=max_cost, max_tokens=max_tokens
|
71
|
+
)
|
68
72
|
return result
|
69
73
|
|
70
74
|
async def _do_all(
|
@@ -123,6 +127,7 @@ def run_batch_tasks(
|
|
123
127
|
batch_size: Optional[int] = None,
|
124
128
|
turns: int = -1,
|
125
129
|
max_cost: float = 0.0,
|
130
|
+
max_tokens: int = 0,
|
126
131
|
) -> List[U]:
|
127
132
|
"""
|
128
133
|
Run copies of `task` async/concurrently one per item in `items` list.
|
@@ -141,6 +146,7 @@ def run_batch_tasks(
|
|
141
146
|
if None, unbatched
|
142
147
|
turns (int): number of turns to run, -1 for infinite
|
143
148
|
max_cost: float: maximum cost to run the task (default 0.0 for unlimited)
|
149
|
+
max_tokens: int: maximum token usage (in and out) (default 0 for unlimited)
|
144
150
|
|
145
151
|
Returns:
|
146
152
|
list[Any]: list of final results
|
@@ -156,6 +162,7 @@ def run_batch_tasks(
|
|
156
162
|
turns,
|
157
163
|
message,
|
158
164
|
max_cost=max_cost,
|
165
|
+
max_tokens=max_tokens,
|
159
166
|
)
|
160
167
|
|
161
168
|
|
@@ -14,7 +14,7 @@ from .table_chat_agent import (
|
|
14
14
|
dataframe_summary,
|
15
15
|
TableChatAgent,
|
16
16
|
TableChatAgentConfig,
|
17
|
-
|
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
|
-
"
|
41
|
+
"PandasEvalTool",
|
42
42
|
"sql",
|
43
43
|
"relevance_extractor_agent",
|
44
44
|
"doc_chat_agent",
|
@@ -117,6 +117,7 @@ class DocChatAgentConfig(ChatAgentConfig):
|
|
117
117
|
)
|
118
118
|
rerank_diversity: bool = True # rerank to maximize diversity?
|
119
119
|
rerank_periphery: bool = True # rerank to avoid Lost In the Middle effect?
|
120
|
+
rerank_after_adding_context: bool = True # rerank after adding context window?
|
120
121
|
embed_batch_size: int = 500 # get embedding of at most this many at a time
|
121
122
|
cache: bool = True # cache results
|
122
123
|
debug: bool = False
|
@@ -1110,9 +1111,10 @@ class DocChatAgent(ChatAgent):
|
|
1110
1111
|
if len(passages) == 0:
|
1111
1112
|
return []
|
1112
1113
|
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1114
|
+
if self.config.rerank_after_adding_context:
|
1115
|
+
passages_scores = [(p, 0.0) for p in passages]
|
1116
|
+
passages_scores = self.add_context_window(passages_scores)
|
1117
|
+
passages = [p for p, _ in passages_scores]
|
1116
1118
|
# now passages can potentially have a lot of doc chunks,
|
1117
1119
|
# so we re-rank them using a cross-encoder scoring model,
|
1118
1120
|
# and pick top k where k = config.parsing.n_similar_docs
|
@@ -1129,6 +1131,11 @@ class DocChatAgent(ChatAgent):
|
|
1129
1131
|
# (see Lost In the Middle issue).
|
1130
1132
|
passages = self.rerank_to_periphery(passages)
|
1131
1133
|
|
1134
|
+
if not self.config.rerank_after_adding_context:
|
1135
|
+
passages_scores = [(p, 0.0) for p in passages]
|
1136
|
+
passages_scores = self.add_context_window(passages_scores)
|
1137
|
+
passages = [p for p, _ in passages_scores]
|
1138
|
+
|
1132
1139
|
return passages
|
1133
1140
|
|
1134
1141
|
@no_type_check
|
@@ -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
|
-
|
7
|
-
|
8
|
-
|
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 `
|
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
|
43
|
-
|
44
|
-
|
45
|
-
|
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 `
|
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 `
|
56
|
+
try using the `pandas_eval` tool/function again with the corrected code.
|
55
57
|
|
56
|
-
VERY IMPORTANT: When using the `
|
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
|
127
|
-
"""Tool/function to
|
128
|
+
class PandasEvalTool(ToolMessage):
|
129
|
+
"""Tool/function to evaluate a pandas expression involving a dataframe `df`"""
|
128
130
|
|
129
|
-
request: str = "
|
131
|
+
request: str = "pandas_eval"
|
130
132
|
purpose: str = """
|
131
|
-
To
|
133
|
+
To eval a pandas <expression> on the dataframe 'df' and
|
132
134
|
return the results to answer a question.
|
133
|
-
IMPORTANT:
|
135
|
+
IMPORTANT: the <expression> field should be a valid pandas expression.
|
134
136
|
"""
|
135
|
-
|
137
|
+
expression: str
|
136
138
|
|
137
139
|
@classmethod
|
138
140
|
def examples(cls) -> List["ToolMessage"]:
|
139
141
|
return [
|
140
|
-
cls(
|
141
|
-
cls(
|
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
|
-
|
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
|
174
|
-
self.enable_message(
|
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,32 @@ 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.
|
184
|
+
self.sent_expression = False
|
183
185
|
return response
|
184
186
|
|
185
|
-
def
|
187
|
+
def pandas_eval(self, msg: PandasEvalTool) -> str:
|
186
188
|
"""
|
187
|
-
Handle a
|
189
|
+
Handle a PandasEvalTool message by evaluating the `expression` field
|
190
|
+
and returning the result.
|
188
191
|
Args:
|
189
|
-
msg (
|
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.
|
195
|
-
|
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
206
|
|
217
207
|
# Evaluate the last line and get the result
|
218
208
|
try:
|
219
|
-
eval_result = pd.eval(
|
209
|
+
eval_result = pd.eval(exprn, local_dict=local_vars)
|
220
210
|
except Exception as e:
|
221
211
|
eval_result = f"ERROR: {type(e)}: {e}"
|
222
212
|
|
@@ -242,15 +232,15 @@ class TableChatAgent(ChatAgent):
|
|
242
232
|
def handle_message_fallback(
|
243
233
|
self, msg: str | ChatDocument
|
244
234
|
) -> str | ChatDocument | None:
|
245
|
-
"""Handle scenario where LLM forgets to say DONE or
|
235
|
+
"""Handle scenario where LLM forgets to say DONE or
|
236
|
+
forgets to use pandas_eval"""
|
246
237
|
if isinstance(msg, ChatDocument) and msg.metadata.sender == lr.Entity.LLM:
|
247
|
-
if self.
|
238
|
+
if self.sent_expression:
|
248
239
|
return DONE
|
249
240
|
else:
|
250
241
|
return """
|
251
|
-
You forgot to use the `
|
252
|
-
|
253
|
-
|
254
|
-
should be in the `code` field.
|
242
|
+
You forgot to use the `pandas_eval` tool/function
|
243
|
+
to find the answer.
|
244
|
+
Try again using the `pandas_eval` tool/function.
|
255
245
|
"""
|
256
246
|
return None
|
langroid/agent/task.py
CHANGED
@@ -171,6 +171,7 @@ class Task:
|
|
171
171
|
if user_message:
|
172
172
|
agent.set_user_message(user_message)
|
173
173
|
self.max_cost: float = 0
|
174
|
+
self.max_tokens: int = 0
|
174
175
|
self.logger: None | RichFileLogger = None
|
175
176
|
self.tsv_logger: None | logging.Logger = None
|
176
177
|
self.color_log: bool = False if settings.notebook else True
|
@@ -376,12 +377,14 @@ class Task:
|
|
376
377
|
turns: int = -1,
|
377
378
|
caller: None | Task = None,
|
378
379
|
max_cost: float = 0,
|
380
|
+
max_tokens: int = 0,
|
379
381
|
) -> Optional[ChatDocument]:
|
380
382
|
"""Synchronous version of `run_async()`.
|
381
383
|
See `run_async()` for details."""
|
382
384
|
self.task_progress = False
|
383
385
|
self.n_stalled_steps = 0
|
384
386
|
self.max_cost = max_cost
|
387
|
+
self.max_tokens = max_tokens
|
385
388
|
assert (
|
386
389
|
msg is None or isinstance(msg, str) or isinstance(msg, ChatDocument)
|
387
390
|
), f"msg arg in Task.run() must be None, str, or ChatDocument, not {type(msg)}"
|
@@ -421,6 +424,7 @@ class Task:
|
|
421
424
|
turns: int = -1,
|
422
425
|
caller: None | Task = None,
|
423
426
|
max_cost: float = 0,
|
427
|
+
max_tokens: int = 0,
|
424
428
|
) -> Optional[ChatDocument]:
|
425
429
|
"""
|
426
430
|
Loop over `step()` until task is considered done or `turns` is reached.
|
@@ -437,7 +441,8 @@ class Task:
|
|
437
441
|
turns (int): number of turns to run the task for;
|
438
442
|
default is -1, which means run until task is done.
|
439
443
|
caller (Task|None): the calling task, if any
|
440
|
-
max_cost (float):
|
444
|
+
max_cost (float): max cost allowed for the task (default 0 -> no limit)
|
445
|
+
max_tokens (int): max tokens allowed for the task (default 0 -> no limit)
|
441
446
|
|
442
447
|
Returns:
|
443
448
|
Optional[ChatDocument]: valid result of the task.
|
@@ -450,6 +455,7 @@ class Task:
|
|
450
455
|
self.task_progress = False
|
451
456
|
self.n_stalled_steps = 0
|
452
457
|
self.max_cost = max_cost
|
458
|
+
self.max_tokens = max_tokens
|
453
459
|
if (
|
454
460
|
isinstance(msg, ChatDocument)
|
455
461
|
and msg.metadata.recipient != ""
|
@@ -826,6 +832,7 @@ class Task:
|
|
826
832
|
turns=actual_turns,
|
827
833
|
caller=self,
|
828
834
|
max_cost=self.max_cost,
|
835
|
+
max_tokens=self.max_tokens,
|
829
836
|
)
|
830
837
|
result_str = str(ChatDocument.to_LLMMessage(result))
|
831
838
|
maybe_tool = len(extract_top_level_json(result_str)) > 0
|
@@ -901,6 +908,8 @@ class Task:
|
|
901
908
|
self.pending_message,
|
902
909
|
turns=actual_turns,
|
903
910
|
caller=self,
|
911
|
+
max_cost=self.max_cost,
|
912
|
+
max_tokens=self.max_tokens,
|
904
913
|
)
|
905
914
|
result_str = str(ChatDocument.to_LLMMessage(result))
|
906
915
|
maybe_tool = len(extract_top_level_json(result_str)) > 0
|
@@ -1062,12 +1071,21 @@ class Task:
|
|
1062
1071
|
try:
|
1063
1072
|
if self.agent.llm.tot_tokens_cost()[1] > self.max_cost:
|
1064
1073
|
logger.warning(
|
1065
|
-
f"Task {self.name} exceeded
|
1074
|
+
f"Task {self.name} cost exceeded {self.max_cost}; exiting."
|
1066
1075
|
)
|
1067
1076
|
return True
|
1068
1077
|
except Exception:
|
1069
1078
|
pass
|
1070
1079
|
|
1080
|
+
if self.max_tokens > 0 and self.agent.llm is not None:
|
1081
|
+
try:
|
1082
|
+
if self.agent.llm.tot_tokens_cost()[0] > self.max_tokens:
|
1083
|
+
logger.warning(
|
1084
|
+
f"Task {self.name} uses > {self.max_tokens} tokens; exiting."
|
1085
|
+
)
|
1086
|
+
return True
|
1087
|
+
except Exception:
|
1088
|
+
pass
|
1071
1089
|
return (
|
1072
1090
|
# no valid response from any entity/agent in current turn
|
1073
1091
|
result is None
|
@@ -1,7 +1,7 @@
|
|
1
1
|
langroid/__init__.py,sha256=qgY-OqzYSWOc6EytQJN9sH2PwDp1UIzP9lXhrYH6aLU,1645
|
2
2
|
langroid/agent/__init__.py,sha256=_D8dxnfdr92ch1CIrUkKjrB5HVvsQdn62b1Fb2kBxV8,785
|
3
3
|
langroid/agent/base.py,sha256=jyGFmojrFuOy81lUkNsJlR6mLIOY6kOD20P9dhEcEuw,35059
|
4
|
-
langroid/agent/batch.py,sha256=
|
4
|
+
langroid/agent/batch.py,sha256=SyvUwKetPH_4JKgTnV0bgXS7eD_qfFl9cq06lnill4o,9956
|
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
|
@@ -9,8 +9,8 @@ langroid/agent/chat_document.py,sha256=PL8iA1ZYjXNFVa3kMO8T4sbbM3rzHWpRAY6PN_7n5
|
|
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=
|
13
|
-
langroid/agent/special/doc_chat_agent.py,sha256=
|
12
|
+
langroid/agent/special/__init__.py,sha256=NG0JkB5y4K0bgnd9Q9UIvFExun3uTfVOWEVLVymff1M,1207
|
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
|
16
16
|
langroid/agent/special/lance_rag/critic_agent.py,sha256=pi_9eMBxEycbWTddtq_yz-mOb2V4SgGm3zfsOH1HU-Q,5775
|
@@ -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
|
35
|
-
langroid/agent/task.py,sha256=
|
34
|
+
langroid/agent/special/table_chat_agent.py,sha256=AXT95SoFOlyWQLXZx_ioRE6EEB3eGHe6Hw6gWz-mBcY,8786
|
35
|
+
langroid/agent/task.py,sha256=jUeKRreYvs_6OlOqVxqfYWQHtvDZViUDtx5wl_b9cyY,51160
|
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
|
@@ -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.
|
124
|
-
langroid-0.1.
|
125
|
-
langroid-0.1.
|
126
|
-
langroid-0.1.
|
123
|
+
langroid-0.1.234.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
124
|
+
langroid-0.1.234.dist-info/METADATA,sha256=603Saz9Bfeqwk04J8_uk3dA_9nZkmcPdYoKe2GuuJs0,47863
|
125
|
+
langroid-0.1.234.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
126
|
+
langroid-0.1.234.dist-info/RECORD,,
|
File without changes
|
File without changes
|