langroid 0.19.5__py3-none-any.whl → 0.20.1__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/base.py +29 -14
- langroid/agent/special/arangodb/arangodb_agent.py +649 -0
- langroid/agent/special/arangodb/system_messages.py +183 -0
- langroid/agent/special/arangodb/tools.py +102 -0
- langroid/agent/special/arangodb/utils.py +36 -0
- langroid/agent/special/neo4j/neo4j_chat_agent.py +120 -54
- langroid/agent/special/neo4j/system_messages.py +120 -0
- langroid/agent/special/neo4j/tools.py +32 -0
- langroid/agent/special/sql/sql_chat_agent.py +8 -3
- langroid/agent/task.py +78 -56
- langroid/agent/tools/orchestration.py +7 -7
- langroid/parsing/parser.py +6 -0
- {langroid-0.19.5.dist-info → langroid-0.20.1.dist-info}/METADATA +5 -1
- {langroid-0.19.5.dist-info → langroid-0.20.1.dist-info}/RECORD +18 -13
- pyproject.toml +7 -1
- langroid/agent/special/neo4j/utils/system_message.py +0 -64
- /langroid/agent/special/{neo4j/utils → arangodb}/__init__.py +0 -0
- {langroid-0.19.5.dist-info → langroid-0.20.1.dist-info}/LICENSE +0 -0
- {langroid-0.19.5.dist-info → langroid-0.20.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
from langroid.agent.special.neo4j.tools import (
|
2
|
+
cypher_creation_tool_name,
|
3
|
+
cypher_retrieval_tool_name,
|
4
|
+
graph_schema_tool_name,
|
5
|
+
)
|
6
|
+
from langroid.agent.tools.orchestration import DoneTool
|
7
|
+
|
8
|
+
done_tool_name = DoneTool.default_value("request")
|
9
|
+
|
10
|
+
graph_schema_tool_description = f"""
|
11
|
+
`{graph_schema_tool_name}` tool/function-call to get all the node labels, relationship
|
12
|
+
types, and property keys available in your Neo4j database. You MUST use
|
13
|
+
this tool BEFORE attempting to use the `{cypher_retrieval_tool_name}` tool,
|
14
|
+
to ensure that you are using the correct node labels, relationship types, and
|
15
|
+
property keys in your `{cypher_retrieval_tool_name}` tool/function-call.
|
16
|
+
"""
|
17
|
+
|
18
|
+
cypher_retrieval_tool_description = f"""
|
19
|
+
`{cypher_retrieval_tool_name}` tool/function-call to retrieve information from the
|
20
|
+
graph database to answer questions.
|
21
|
+
"""
|
22
|
+
|
23
|
+
cypher_creation_tool_description = f"""
|
24
|
+
`{cypher_creation_tool_name}` tool/function-call to execute cypher query that creates
|
25
|
+
entities/relationships in the graph database.
|
26
|
+
"""
|
27
|
+
|
28
|
+
cypher_query_instructions = """
|
29
|
+
You must be smart about using the right node labels, relationship types, and property
|
30
|
+
keys based on the english description. If you are thinking of using a node label,
|
31
|
+
relationship type, or property key that does not exist, you are probably on the wrong
|
32
|
+
track, so you should try your best to answer based on an existing table or column.
|
33
|
+
DO NOT assume any nodes or relationships other than those above.
|
34
|
+
"""
|
35
|
+
|
36
|
+
|
37
|
+
# sys msg to use when schema already provided initially,
|
38
|
+
# so agent does not need to use schema tool, at least initially,
|
39
|
+
# but may do so later if the db evolves, or if needs to bring in the schema
|
40
|
+
# to more recent context.
|
41
|
+
SCHEMA_PROVIDED_SYS_MSG = f"""You are a data scientist and expert in Knowledge Graphs,
|
42
|
+
with expertise in answering questions by interacting with a Neo4j graph database.
|
43
|
+
|
44
|
+
The schema below describes the Neo4j database structure, node labels,
|
45
|
+
relationship types, and property keys available in your Neo4j database.
|
46
|
+
|
47
|
+
=== SCHEMA ===
|
48
|
+
{{schema}}
|
49
|
+
=== END SCHEMA ===
|
50
|
+
|
51
|
+
To help with the user's question or database update/creation request,
|
52
|
+
you have access to these tools:
|
53
|
+
|
54
|
+
- {cypher_retrieval_tool_description}
|
55
|
+
|
56
|
+
- {cypher_creation_tool_description}
|
57
|
+
|
58
|
+
Since the schema has been provided, you may not need to use the tool below,
|
59
|
+
but you may use it if you need to remind yourself about the schema:
|
60
|
+
|
61
|
+
- {graph_schema_tool_description}
|
62
|
+
|
63
|
+
"""
|
64
|
+
|
65
|
+
# sys msg to use when schema is not initially provided,
|
66
|
+
# and we want agent to use schema tool to get schema
|
67
|
+
SCHEMA_TOOLS_SYS_MSG = f"""You are a data scientist and expert in Knowledge Graphs,
|
68
|
+
with expertise in answering questions by querying Neo4j database.
|
69
|
+
You have access to the following tools:
|
70
|
+
|
71
|
+
- {graph_schema_tool_description}
|
72
|
+
|
73
|
+
- {cypher_retrieval_tool_description}
|
74
|
+
|
75
|
+
- {cypher_creation_tool_description}
|
76
|
+
|
77
|
+
"""
|
78
|
+
|
79
|
+
DEFAULT_NEO4J_CHAT_SYSTEM_MESSAGE = f"""
|
80
|
+
{{mode}}
|
81
|
+
|
82
|
+
You do not need to be able to answer a question with just one query.
|
83
|
+
You could make a sequence of Cypher queries to find the answer to the question.
|
84
|
+
|
85
|
+
{cypher_query_instructions}
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
RETRY-SUGGESTIONS:
|
90
|
+
If you receive a null or other unexpected result,
|
91
|
+
(a) make sure you use the available TOOLs correctly,
|
92
|
+
(b) USE `{graph_schema_tool_name}` tool/function-call to get all the node labels,
|
93
|
+
relationship types, and property keys available in your Neo4j database.
|
94
|
+
(c) LABELS are CASE-SENSITIVE -- make sure you adhere to the exact label name
|
95
|
+
you found in the schema.
|
96
|
+
(d) see if you have made an assumption in your Neo4j query, and try another way,
|
97
|
+
or use `{cypher_retrieval_tool_name}` to explore the database contents before
|
98
|
+
submitting your final query.
|
99
|
+
(e) USE `{cypher_creation_tool_name}` tool/function-call to execute cypher query that
|
100
|
+
creates entities/relationships in the graph database.
|
101
|
+
(f) Try APPROXIMATE or PARTIAL MATCHES to strings in the user's query,
|
102
|
+
e.g. user may ask about "Godfather" instead of "The Godfather",
|
103
|
+
or try using CASE-INSENSITIVE MATCHES.
|
104
|
+
|
105
|
+
Start by asking what the user needs help with.
|
106
|
+
"""
|
107
|
+
|
108
|
+
ADDRESSING_INSTRUCTION = """
|
109
|
+
IMPORTANT - Whenever you are NOT writing a CYPHER query, make sure you address the
|
110
|
+
user using {prefix}User. You MUST use the EXACT syntax {prefix} !!!
|
111
|
+
|
112
|
+
In other words, you ALWAYS EITHER:
|
113
|
+
- write a CYPHER query using one of the tools,
|
114
|
+
- OR address the user using {prefix}User.
|
115
|
+
"""
|
116
|
+
|
117
|
+
DONE_INSTRUCTION = f"""
|
118
|
+
When you finally have the answer to a user's query or request,
|
119
|
+
use the `{done_tool_name}` with `content` set to the answer or result.
|
120
|
+
"""
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from langroid.agent import ToolMessage
|
2
|
+
|
3
|
+
|
4
|
+
class CypherRetrievalTool(ToolMessage):
|
5
|
+
request: str = "cypher_retrieval_tool"
|
6
|
+
purpose: str = """To send the <cypher_query> to retrieve
|
7
|
+
data from the graph database based on provided text description and schema.
|
8
|
+
"""
|
9
|
+
cypher_query: str
|
10
|
+
|
11
|
+
|
12
|
+
cypher_retrieval_tool_name = CypherRetrievalTool.default_value("request")
|
13
|
+
|
14
|
+
|
15
|
+
class CypherCreationTool(ToolMessage):
|
16
|
+
request: str = "cypher_creation_tool"
|
17
|
+
purpose: str = """
|
18
|
+
To send the <cypher_query> to create
|
19
|
+
entities/relationships in the graph database.
|
20
|
+
"""
|
21
|
+
cypher_query: str
|
22
|
+
|
23
|
+
|
24
|
+
cypher_creation_tool_name = CypherCreationTool.default_value("request")
|
25
|
+
|
26
|
+
|
27
|
+
class GraphSchemaTool(ToolMessage):
|
28
|
+
request: str = "graph_schema_tool"
|
29
|
+
purpose: str = """To get the schema of the graph database."""
|
30
|
+
|
31
|
+
|
32
|
+
graph_schema_tool_name = GraphSchemaTool.default_value("request")
|
@@ -14,7 +14,7 @@ from rich import print
|
|
14
14
|
from rich.console import Console
|
15
15
|
|
16
16
|
from langroid.exceptions import LangroidImportError
|
17
|
-
from langroid.utils.constants import DONE
|
17
|
+
from langroid.utils.constants import DONE, SEND_TO
|
18
18
|
|
19
19
|
try:
|
20
20
|
from sqlalchemy import MetaData, Row, create_engine, inspect, text
|
@@ -96,7 +96,7 @@ class SQLChatAgentConfig(ChatAgentConfig):
|
|
96
96
|
context_descriptions: Dict[str, Dict[str, Union[str, Dict[str, str]]]] = {}
|
97
97
|
use_schema_tools: bool = False
|
98
98
|
multi_schema: bool = False
|
99
|
-
addressing_prefix: str =
|
99
|
+
addressing_prefix: str = SEND_TO
|
100
100
|
|
101
101
|
"""
|
102
102
|
Optional, but strongly recommended, context descriptions for tables, columns,
|
@@ -257,6 +257,7 @@ class SQLChatAgent(ChatAgent):
|
|
257
257
|
self, message: Optional[str | ChatDocument] = None
|
258
258
|
) -> Optional[ChatDocument]:
|
259
259
|
self.llm_responded = True
|
260
|
+
self.used_run_query = False
|
260
261
|
return super().llm_response(message)
|
261
262
|
|
262
263
|
def user_response(
|
@@ -270,7 +271,11 @@ class SQLChatAgent(ChatAgent):
|
|
270
271
|
def handle_message_fallback(
|
271
272
|
self, msg: str | ChatDocument
|
272
273
|
) -> str | ChatDocument | None:
|
273
|
-
|
274
|
+
"""
|
275
|
+
Handle the scenario where current msg is not a tool.
|
276
|
+
Special handling is only needed if the message was from the LLM
|
277
|
+
(as indicated by self.llm_responded).
|
278
|
+
"""
|
274
279
|
if not self.llm_responded:
|
275
280
|
return None
|
276
281
|
if self.used_run_query:
|
langroid/agent/task.py
CHANGED
@@ -1226,7 +1226,6 @@ class Task:
|
|
1226
1226
|
# reset stuck counter since we made progress
|
1227
1227
|
self.n_stalled_steps = 0
|
1228
1228
|
|
1229
|
-
|
1230
1229
|
if self.pending_message is not None:
|
1231
1230
|
if (
|
1232
1231
|
self._is_done_response(result, r)
|
@@ -1331,6 +1330,9 @@ class Task:
|
|
1331
1330
|
max_cost=self.max_cost,
|
1332
1331
|
max_tokens=self.max_tokens,
|
1333
1332
|
)
|
1333
|
+
# update result.tool_messages if any
|
1334
|
+
if isinstance(result, ChatDocument):
|
1335
|
+
self.agent.get_tool_messages(result)
|
1334
1336
|
if result is not None:
|
1335
1337
|
content, id2result, oai_tool_id = self.agent.process_tool_results(
|
1336
1338
|
result.content,
|
@@ -1359,6 +1361,9 @@ class Task:
|
|
1359
1361
|
else:
|
1360
1362
|
response_fn = self._entity_responder_map[cast(Entity, e)]
|
1361
1363
|
result = response_fn(self.pending_message)
|
1364
|
+
# update result.tool_messages if any
|
1365
|
+
if isinstance(result, ChatDocument):
|
1366
|
+
self.agent.get_tool_messages(result)
|
1362
1367
|
|
1363
1368
|
result_chat_doc = self.agent.to_ChatDocument(
|
1364
1369
|
result,
|
@@ -1389,7 +1394,7 @@ class Task:
|
|
1389
1394
|
# ignore all string-based signaling/routing
|
1390
1395
|
return result
|
1391
1396
|
# parse various routing/addressing strings in result
|
1392
|
-
is_pass, recipient, content =
|
1397
|
+
is_pass, recipient, content = self._parse_routing(
|
1393
1398
|
result,
|
1394
1399
|
addressing_prefix=self.config.addressing_prefix,
|
1395
1400
|
)
|
@@ -1522,7 +1527,7 @@ class Task:
|
|
1522
1527
|
oai_tool_id2result = result_msg.oai_tool_id2result if result_msg else None
|
1523
1528
|
fun_call = result_msg.function_call if result_msg else None
|
1524
1529
|
tool_messages = result_msg.tool_messages if result_msg else []
|
1525
|
-
# if there is an
|
1530
|
+
# if there is an DoneTool or AgentDoneTool among these,
|
1526
1531
|
# we extract content and tools from here, and ignore all others
|
1527
1532
|
for t in tool_messages:
|
1528
1533
|
if isinstance(t, FinalResultTool):
|
@@ -1534,6 +1539,8 @@ class Task:
|
|
1534
1539
|
# there shouldn't be multiple tools like this; just take the first
|
1535
1540
|
content = to_string(t.content)
|
1536
1541
|
content_any = t.content
|
1542
|
+
fun_call = None
|
1543
|
+
oai_tool_calls = None
|
1537
1544
|
if isinstance(t, AgentDoneTool):
|
1538
1545
|
# AgentDoneTool may have tools, unlike DoneTool
|
1539
1546
|
tool_messages = t.tools
|
@@ -1906,6 +1913,7 @@ class Task:
|
|
1906
1913
|
# user, then wait for user response
|
1907
1914
|
self.pending_message is not None
|
1908
1915
|
and self.pending_message.metadata.recipient == Entity.USER
|
1916
|
+
and not self.agent.has_tool_message_attempt(self.pending_message)
|
1909
1917
|
)
|
1910
1918
|
|
1911
1919
|
def _can_respond(self, e: Responder) -> bool:
|
@@ -1940,58 +1948,72 @@ class Task:
|
|
1940
1948
|
"""
|
1941
1949
|
self.color_log = enable
|
1942
1950
|
|
1951
|
+
def _parse_routing(
|
1952
|
+
self,
|
1953
|
+
msg: ChatDocument | str,
|
1954
|
+
addressing_prefix: str = "",
|
1955
|
+
) -> Tuple[bool | None, str | None, str | None]:
|
1956
|
+
"""
|
1957
|
+
Parse routing instruction if any, of the form:
|
1958
|
+
PASS:<recipient> (pass current pending msg to recipient)
|
1959
|
+
SEND:<recipient> <content> (send content to recipient)
|
1960
|
+
@<recipient> <content> (send content to recipient)
|
1961
|
+
Args:
|
1962
|
+
msg (ChatDocument|str|None): message to parse
|
1963
|
+
addressing_prefix (str): prefix to address other agents or entities,
|
1964
|
+
(e.g. "@". See documentation of `TaskConfig` for details).
|
1965
|
+
Returns:
|
1966
|
+
Tuple[bool|None, str|None, str|None]:
|
1967
|
+
bool: true=PASS, false=SEND, or None if neither
|
1968
|
+
str: recipient, or None
|
1969
|
+
str: content to send, or None
|
1970
|
+
"""
|
1971
|
+
# handle routing instruction-strings in result if any,
|
1972
|
+
# such as PASS, PASS_TO, or SEND
|
1943
1973
|
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
is not None
|
1989
|
-
):
|
1990
|
-
(addressee, content_to_send) = addressee_content
|
1991
|
-
# if no content then treat same as PASS_TO
|
1992
|
-
if content_to_send == "":
|
1993
|
-
return True, addressee, None
|
1994
|
-
else:
|
1995
|
-
return False, addressee, content_to_send
|
1974
|
+
msg_str = msg.content if isinstance(msg, ChatDocument) else msg
|
1975
|
+
if (
|
1976
|
+
self.agent.has_tool_message_attempt(msg)
|
1977
|
+
and not msg_str.startswith(PASS)
|
1978
|
+
and not msg_str.startswith(PASS_TO)
|
1979
|
+
and not msg_str.startswith(SEND_TO)
|
1980
|
+
):
|
1981
|
+
# if there's an attempted tool-call, we ignore any routing strings,
|
1982
|
+
# unless they are at the start of the msg
|
1983
|
+
return None, None, None
|
1984
|
+
|
1985
|
+
content = msg.content if isinstance(msg, ChatDocument) else msg
|
1986
|
+
content = content.strip()
|
1987
|
+
if PASS in content and PASS_TO not in content:
|
1988
|
+
return True, None, None
|
1989
|
+
if PASS_TO in content and content.split(":")[1] != "":
|
1990
|
+
return True, content.split(":")[1], None
|
1991
|
+
if (
|
1992
|
+
SEND_TO in content
|
1993
|
+
and (addressee_content := parse_addressed_message(content, SEND_TO))[0]
|
1994
|
+
is not None
|
1995
|
+
):
|
1996
|
+
# Note this will discard any portion of content BEFORE SEND_TO.
|
1997
|
+
# TODO maybe make this configurable.
|
1998
|
+
(addressee, content_to_send) = addressee_content
|
1999
|
+
# if no content then treat same as PASS_TO
|
2000
|
+
if content_to_send == "":
|
2001
|
+
return True, addressee, None
|
2002
|
+
else:
|
2003
|
+
return False, addressee, content_to_send
|
2004
|
+
if (
|
2005
|
+
addressing_prefix != ""
|
2006
|
+
and addressing_prefix in content
|
2007
|
+
and (
|
2008
|
+
addressee_content := parse_addressed_message(content, addressing_prefix)
|
2009
|
+
)[0]
|
2010
|
+
is not None
|
2011
|
+
):
|
2012
|
+
(addressee, content_to_send) = addressee_content
|
2013
|
+
# if no content then treat same as PASS_TO
|
2014
|
+
if content_to_send == "":
|
2015
|
+
return True, addressee, None
|
2016
|
+
else:
|
2017
|
+
return False, addressee, content_to_send
|
1996
2018
|
|
1997
|
-
|
2019
|
+
return None, None, None
|
@@ -41,11 +41,11 @@ class DoneTool(ToolMessage):
|
|
41
41
|
"""Tool for Agent Entity (i.e. agent_response) or LLM entity (i.e. llm_response) to
|
42
42
|
signal the current task is done, with some content as the result."""
|
43
43
|
|
44
|
-
purpose = """
|
44
|
+
purpose: str = """
|
45
45
|
To signal the current task is done, along with an optional message <content>
|
46
46
|
of arbitrary type (default None).
|
47
47
|
"""
|
48
|
-
request = "done_tool"
|
48
|
+
request: str = "done_tool"
|
49
49
|
content: str = ""
|
50
50
|
|
51
51
|
def response(self, agent: ChatAgent) -> ChatDocument:
|
@@ -77,7 +77,7 @@ class ResultTool(ToolMessage):
|
|
77
77
|
Note:
|
78
78
|
- when defining a tool handler or agent_response, you can directly return
|
79
79
|
ResultTool(field1 = val1, ...),
|
80
|
-
where the values can be
|
80
|
+
where the values can be arbitrary data structures, including nested
|
81
81
|
Pydantic objs, or you can define a subclass of ResultTool with the
|
82
82
|
fields you want to return.
|
83
83
|
- This is a special ToolMessage that is NOT meant to be used or handled
|
@@ -143,10 +143,10 @@ class PassTool(ToolMessage):
|
|
143
143
|
Similar to ForwardTool, but without specifying the recipient agent.
|
144
144
|
"""
|
145
145
|
|
146
|
-
purpose = """
|
146
|
+
purpose: str = """
|
147
147
|
To pass the current message so that other agents can handle it.
|
148
148
|
"""
|
149
|
-
request = "pass_tool"
|
149
|
+
request: str = "pass_tool"
|
150
150
|
|
151
151
|
def response(self, agent: ChatAgent, chat_doc: ChatDocument) -> ChatDocument:
|
152
152
|
"""When this tool is enabled for an Agent, this will result in a method
|
@@ -178,10 +178,10 @@ class DonePassTool(PassTool):
|
|
178
178
|
Similar to PassTool, except we append a DoneTool to the result tool_messages.
|
179
179
|
"""
|
180
180
|
|
181
|
-
purpose = """
|
181
|
+
purpose: str = """
|
182
182
|
To signal the current task is done, with results set to the current/incoming msg.
|
183
183
|
"""
|
184
|
-
request = "done_pass_tool"
|
184
|
+
request: str = "done_pass_tool"
|
185
185
|
|
186
186
|
def response(self, agent: ChatAgent, chat_doc: ChatDocument) -> ChatDocument:
|
187
187
|
# use PassTool to get the right ChatDocument to pass...
|
langroid/parsing/parser.py
CHANGED
@@ -66,6 +66,12 @@ class Parser:
|
|
66
66
|
tokens = self.tokenizer.encode(text)
|
67
67
|
return len(tokens)
|
68
68
|
|
69
|
+
def truncate_tokens(self, text: str, max_tokens: int) -> str:
|
70
|
+
tokens = self.tokenizer.encode(text)
|
71
|
+
if len(tokens) <= max_tokens:
|
72
|
+
return text
|
73
|
+
return self.tokenizer.decode(tokens[:max_tokens])
|
74
|
+
|
69
75
|
def add_window_ids(self, chunks: List[Document]) -> None:
|
70
76
|
"""Chunks may belong to multiple docs, but for each doc,
|
71
77
|
they appear consecutively. Add window_ids in metadata"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.20.1
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
License: MIT
|
6
6
|
Author: Prasad Chalasani
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
14
|
Provides-Extra: all
|
15
|
+
Provides-Extra: arango
|
15
16
|
Provides-Extra: chainlit
|
16
17
|
Provides-Extra: chromadb
|
17
18
|
Provides-Extra: db
|
@@ -35,7 +36,9 @@ Provides-Extra: sql
|
|
35
36
|
Provides-Extra: transformers
|
36
37
|
Provides-Extra: unstructured
|
37
38
|
Provides-Extra: vecdbs
|
39
|
+
Requires-Dist: adb-cloud-connector (>=1.0.2,<2.0.0)
|
38
40
|
Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
|
41
|
+
Requires-Dist: arango-datasets (>=1.2.2,<2.0.0) ; extra == "all" or extra == "arango"
|
39
42
|
Requires-Dist: async-generator (>=1.10,<2.0)
|
40
43
|
Requires-Dist: bs4 (>=0.0.1,<0.0.2)
|
41
44
|
Requires-Dist: cerebras-cloud-sdk (>=1.1.0,<2.0.0)
|
@@ -82,6 +85,7 @@ Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "db" or extra == "all" or ext
|
|
82
85
|
Requires-Dist: pyparsing (>=3.0.9,<4.0.0)
|
83
86
|
Requires-Dist: pypdf (>=3.12.2,<4.0.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
|
84
87
|
Requires-Dist: pytesseract (>=0.3.10,<0.4.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
|
88
|
+
Requires-Dist: python-arango (>=8.1.2,<9.0.0) ; extra == "all" or extra == "arango"
|
85
89
|
Requires-Dist: python-docx (>=1.1.0,<2.0.0) ; extra == "doc-chat" or extra == "all" or extra == "docx"
|
86
90
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
87
91
|
Requires-Dist: python-magic (>=0.4.27,<0.5.0)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
langroid/__init__.py,sha256=z_fCOLQJPOw3LLRPBlFB5-2HyCjpPgQa4m4iY5Fvb8Y,1800
|
2
2
|
langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,786
|
3
|
-
langroid/agent/base.py,sha256=
|
3
|
+
langroid/agent/base.py,sha256=sOZapdzHaB4kbCLu8vI_zZx78jIhv9fmWn0EWV4yTAE,65371
|
4
4
|
langroid/agent/batch.py,sha256=QZdlt1563hx4l3AXrCaGovE-PNG93M3DsvQAbDzdiS8,13705
|
5
5
|
langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
langroid/agent/callbacks/chainlit.py,sha256=JJXI3UGTyTDg2FFath4rqY1GyUo_0pbVBt8CZpvdtn4,23289
|
@@ -10,6 +10,11 @@ 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=2rjCZw45ysNBEGNzQM4uf0bTC4KkatGYAWcVcW4xcek,34337
|
12
12
|
langroid/agent/special/__init__.py,sha256=gik_Xtm_zV7U9s30Mn8UX3Gyuy4jTjQe9zjiE3HWmEo,1273
|
13
|
+
langroid/agent/special/arangodb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
langroid/agent/special/arangodb/arangodb_agent.py,sha256=y9zp2ZQcKkNsUegvDZryn79exth3T-hsmkR-z4gSU-w,25522
|
15
|
+
langroid/agent/special/arangodb/system_messages.py,sha256=Uni6uDOSZpD9miCNzx7CEQjnyxDF8Egbe-hFvkraSt4,6739
|
16
|
+
langroid/agent/special/arangodb/tools.py,sha256=WasFERC1cToLOWi1cWqUs-TujU0A68gZWbhbP128obo,3499
|
17
|
+
langroid/agent/special/arangodb/utils.py,sha256=LIevtkayIdVVXyj3jlbKH2WgdZTtH5-JLgbXOHC7uxs,1420
|
13
18
|
langroid/agent/special/doc_chat_agent.py,sha256=xIqBOyLax_jMU0UevxqXf_aQUrRkW6MQUKpKnKvaqkQ,59281
|
14
19
|
langroid/agent/special/lance_doc_chat_agent.py,sha256=s8xoRs0gGaFtDYFUSIRchsgDVbS5Q3C2b2mr3V1Fd-Q,10419
|
15
20
|
langroid/agent/special/lance_rag/__init__.py,sha256=QTbs0IVE2ZgDg8JJy1zN97rUUg4uEPH7SLGctFNumk4,174
|
@@ -19,13 +24,13 @@ langroid/agent/special/lance_rag/query_planner_agent.py,sha256=5YPeliCjlRk1LEDe5
|
|
19
24
|
langroid/agent/special/lance_tools.py,sha256=qS8x4wi8mrqfbYV2ztFzrcxyhHQ0ZWOc-zkYiH7awj0,2105
|
20
25
|
langroid/agent/special/neo4j/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
26
|
langroid/agent/special/neo4j/csv_kg_chat.py,sha256=dRsAgMBa1H_EMI2YYgJR2Xyv1D7e4o3G9M64mTewq_c,6409
|
22
|
-
langroid/agent/special/neo4j/neo4j_chat_agent.py,sha256=
|
23
|
-
langroid/agent/special/neo4j/
|
24
|
-
langroid/agent/special/neo4j/
|
27
|
+
langroid/agent/special/neo4j/neo4j_chat_agent.py,sha256=1RMKupJra0KZ-hA7AiiR662STJyYDZi8ZnAnnXF8oCA,16726
|
28
|
+
langroid/agent/special/neo4j/system_messages.py,sha256=m2jsVayey6E_88F5B_gW2WbWKBJvIeDUoVCRBbNs97o,4522
|
29
|
+
langroid/agent/special/neo4j/tools.py,sha256=Vw3HvtDfG2c4_bUHgt4_ZbJq48lpIQstbjjwhh1BjrQ,905
|
25
30
|
langroid/agent/special/relevance_extractor_agent.py,sha256=zIx8GUdVo1aGW6ASla0NPQjYYIpmriK_TYMijqAx3F8,4796
|
26
31
|
langroid/agent/special/retriever_agent.py,sha256=lvMvf-u9rSosg4YASuFdUbGLgkzLPknXAbJZfZ1LZCc,1868
|
27
32
|
langroid/agent/special/sql/__init__.py,sha256=mWfmm1QpXCezpFOS2eI57M0L_Ok3q5_ukG8tXBnBrEA,319
|
28
|
-
langroid/agent/special/sql/sql_chat_agent.py,sha256=
|
33
|
+
langroid/agent/special/sql/sql_chat_agent.py,sha256=LVTuOlaY6m5DpsMFLFv00eOz04y6vKeO4mfGLIUp6AY,16844
|
29
34
|
langroid/agent/special/sql/utils/__init__.py,sha256=JFif6CRTrN-bc91uuAI4K9fe2ndIWSNMVxJ0WA68--M,446
|
30
35
|
langroid/agent/special/sql/utils/description_extractors.py,sha256=cX8TIpmTPXZXQTMpIi3OUFwFsPywxFFdurpx717Kq0I,6529
|
31
36
|
langroid/agent/special/sql/utils/populate_metadata.py,sha256=1J22UsyEPKzwK0XlJZtYn9r6kYc0FXIr8-lZrndYlhc,3131
|
@@ -33,14 +38,14 @@ langroid/agent/special/sql/utils/system_message.py,sha256=qKLHkvQWRQodTtPLPxr1GS
|
|
33
38
|
langroid/agent/special/sql/utils/tools.py,sha256=vFYysk6Vi7HJjII8B4RitA3pt_z3gkSglDNdhNVMiFc,1332
|
34
39
|
langroid/agent/special/table_chat_agent.py,sha256=d9v2wsblaRx7oMnKhLV7uO_ujvk9gh59pSGvBXyeyNc,9659
|
35
40
|
langroid/agent/structured_message.py,sha256=y7pud1EgRNeTFZlJmBkLmwME3yQJ_IYik-Xds9kdZbY,282
|
36
|
-
langroid/agent/task.py,sha256=
|
41
|
+
langroid/agent/task.py,sha256=f7clh6p6Md0G4YGHqbFeeT88U4XoP0i3eatekV21hHE,86643
|
37
42
|
langroid/agent/tool_message.py,sha256=jkN7uq7YwUC_wBcSCNUYjrB_His2YCfQay_lqIa4Tww,10498
|
38
43
|
langroid/agent/tools/__init__.py,sha256=IMgCte-_ZIvCkozGQmvMqxIw7_nKLKzD78ccJL1bnQU,804
|
39
44
|
langroid/agent/tools/duckduckgo_search_tool.py,sha256=NhsCaGZkdv28nja7yveAhSK_w6l_Ftym8agbrdzqgfo,1935
|
40
45
|
langroid/agent/tools/file_tools.py,sha256=GjPB5YDILucYapElnvvoYpGJuZQ25ecLs2REv7edPEo,7292
|
41
46
|
langroid/agent/tools/google_search_tool.py,sha256=y7b-3FtgXf0lfF4AYxrZ3K5pH2dhidvibUOAGBE--WI,1456
|
42
47
|
langroid/agent/tools/metaphor_search_tool.py,sha256=qj4gt453cLEX3EGW7nVzVu6X7LCdrwjSlcNY0qJW104,2489
|
43
|
-
langroid/agent/tools/orchestration.py,sha256=
|
48
|
+
langroid/agent/tools/orchestration.py,sha256=EDv1EMVGYqX82x3bCRbTn9gFNs66oosiUM8WTSZkUJg,10909
|
44
49
|
langroid/agent/tools/recipient_tool.py,sha256=dr0yTxgNEIoxUYxH6TtaExC4G_8WdJ0xGohIa4dFLhY,9808
|
45
50
|
langroid/agent/tools/retrieval_tool.py,sha256=2q2pfoYbZNfbWQ0McxrtmfF0ekGglIgRl-6uF26pa-E,871
|
46
51
|
langroid/agent/tools/rewind_tool.py,sha256=XAXL3BpNhCmBGYq_qi_sZfHJuIw7NY2jp4wnojJ7WRs,5606
|
@@ -86,7 +91,7 @@ langroid/parsing/document_parser.py,sha256=ZGxgG4ytnCIah4HWk3ZrK3EGAMXDjAzI9KaPE
|
|
86
91
|
langroid/parsing/image_text.py,sha256=sbLIQ5nHe2UnYUksBaQsmZGaX-X0qgEpPd7CEzi_z5M,910
|
87
92
|
langroid/parsing/para_sentence_split.py,sha256=AJBzZojP3zpB-_IMiiHismhqcvkrVBQ3ZINoQyx_bE4,2000
|
88
93
|
langroid/parsing/parse_json.py,sha256=aADo38bAHQhC8on4aWZZzVzSDy-dK35vRLZsFI2ewh8,4756
|
89
|
-
langroid/parsing/parser.py,sha256=
|
94
|
+
langroid/parsing/parser.py,sha256=bTG5TO2CEwGdLf9979j9_dFntKX5FloGF8vhts6ObU0,11978
|
90
95
|
langroid/parsing/repo_loader.py,sha256=3GjvPJS6Vf5L6gV2zOU8s-Tf1oq_fZm-IB_RL_7CTsY,29373
|
91
96
|
langroid/parsing/routing.py,sha256=-FcnlqldzL4ZoxuDwXjQPNHgBe9F9-F4R6q7b_z9CvI,1232
|
92
97
|
langroid/parsing/search.py,sha256=0i_r0ESb5HEQfagA2g7_uMQyxYPADWVbdcN9ixZhS4E,8992
|
@@ -137,8 +142,8 @@ langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3Hmh
|
|
137
142
|
langroid/vector_store/momento.py,sha256=qR-zBF1RKVHQZPZQYW_7g-XpTwr46p8HJuYPCkfJbM4,10534
|
138
143
|
langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
|
139
144
|
langroid/vector_store/qdrantdb.py,sha256=v88lqFkepADvlN6lByUj9I4NEKa9X9lWH16uTPPbYrE,17457
|
140
|
-
pyproject.toml,sha256=
|
141
|
-
langroid-0.
|
142
|
-
langroid-0.
|
143
|
-
langroid-0.
|
144
|
-
langroid-0.
|
145
|
+
pyproject.toml,sha256=m6gT-kRBlRmBQ50VGLcLDXOmo3MmaYPAHxbySfpGd1E,7488
|
146
|
+
langroid-0.20.1.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
147
|
+
langroid-0.20.1.dist-info/METADATA,sha256=8qg7AF3qK12XRvtEqpR2P8eyidON7E4womWSiY3QW_E,56758
|
148
|
+
langroid-0.20.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
149
|
+
langroid-0.20.1.dist-info/RECORD,,
|
pyproject.toml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "langroid"
|
3
|
-
version = "0.
|
3
|
+
version = "0.20.1"
|
4
4
|
description = "Harness LLMs with Multi-Agent Programming"
|
5
5
|
authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
|
6
6
|
readme = "README.md"
|
@@ -90,6 +90,9 @@ python-magic = "^0.4.27"
|
|
90
90
|
json-repair = "^0.29.9"
|
91
91
|
cerebras-cloud-sdk = "^1.1.0"
|
92
92
|
gitpython = "^3.1.43"
|
93
|
+
python-arango = {version="^8.1.2", optional=true}
|
94
|
+
arango-datasets = {version="^1.2.2", optional=true}
|
95
|
+
adb-cloud-connector = "^1.0.2"
|
93
96
|
|
94
97
|
|
95
98
|
[tool.poetry.extras]
|
@@ -113,6 +116,7 @@ all = [
|
|
113
116
|
# "lancedb", "tantivy", "pyarrow",
|
114
117
|
"chromadb",
|
115
118
|
"metaphor-python", "neo4j",
|
119
|
+
"python-arango", "arango-datasets",
|
116
120
|
"litellm",
|
117
121
|
"chainlit", "python-socketio",
|
118
122
|
"fastembed"
|
@@ -130,6 +134,7 @@ mysql = ["pymysql"]
|
|
130
134
|
sql = ["sqlalchemy", "pymysql", "psycopg2"]
|
131
135
|
litellm = ["litellm"]
|
132
136
|
neo4j = ["neo4j"]
|
137
|
+
arango = ["python-arango", "arango-datasets"]
|
133
138
|
metaphor = ["metaphor-python"]
|
134
139
|
chainlit = ["chainlit", "python-socketio"]
|
135
140
|
chromadb = ["chromadb"]
|
@@ -166,6 +171,7 @@ coverage = "^7.2.5"
|
|
166
171
|
pytest-xdist = "^3.6.1"
|
167
172
|
pytest-timeout = "^2.3.1"
|
168
173
|
pytest-cov = "^5.0.0"
|
174
|
+
docker = "^7.1.0"
|
169
175
|
|
170
176
|
[tool.poetry.group.docs]
|
171
177
|
optional = true
|