langroid 0.10.0__py3-none-any.whl → 0.10.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 +57 -44
- langroid/agent/special/lance_rag/lance_rag_task.py +2 -0
- langroid/agent/tool_message.py +11 -0
- langroid/parsing/code_parser.py +2 -0
- {langroid-0.10.0.dist-info → langroid-0.10.1.dist-info}/METADATA +4 -1
- {langroid-0.10.0.dist-info → langroid-0.10.1.dist-info}/RECORD +9 -9
- pyproject.toml +1 -1
- {langroid-0.10.0.dist-info → langroid-0.10.1.dist-info}/LICENSE +0 -0
- {langroid-0.10.0.dist-info → langroid-0.10.1.dist-info}/WHEEL +0 -0
langroid/agent/base.py
CHANGED
@@ -1069,9 +1069,12 @@ class Agent(ABC):
|
|
1069
1069
|
return None
|
1070
1070
|
if len(tools) == 0:
|
1071
1071
|
fallback_result = self.handle_message_fallback(msg)
|
1072
|
-
if fallback_result is
|
1073
|
-
return
|
1074
|
-
return
|
1072
|
+
if fallback_result is None:
|
1073
|
+
return None
|
1074
|
+
return self._process_handle_message_result(
|
1075
|
+
fallback_result,
|
1076
|
+
chat_doc=msg if isinstance(msg, ChatDocument) else None,
|
1077
|
+
)
|
1075
1078
|
has_ids = all([t.id != "" for t in tools])
|
1076
1079
|
chat_doc = msg if isinstance(msg, ChatDocument) else None
|
1077
1080
|
|
@@ -1162,9 +1165,7 @@ class Agent(ABC):
|
|
1162
1165
|
final = "\n\n".join(str_results)
|
1163
1166
|
return final
|
1164
1167
|
|
1165
|
-
def handle_message_fallback(
|
1166
|
-
self, msg: str | ChatDocument
|
1167
|
-
) -> str | ChatDocument | None:
|
1168
|
+
def handle_message_fallback(self, msg: str | ChatDocument) -> Any:
|
1168
1169
|
"""
|
1169
1170
|
Fallback method for the "no-tools" scenario.
|
1170
1171
|
This method can be overridden by subclasses, e.g.,
|
@@ -1174,8 +1175,7 @@ class Agent(ABC):
|
|
1174
1175
|
Args:
|
1175
1176
|
msg (str | ChatDocument): The input msg to handle
|
1176
1177
|
Returns:
|
1177
|
-
|
1178
|
-
be handled by LLM
|
1178
|
+
Any: The result of the handler method
|
1179
1179
|
"""
|
1180
1180
|
return None
|
1181
1181
|
|
@@ -1261,6 +1261,52 @@ class Agent(ABC):
|
|
1261
1261
|
raise ve
|
1262
1262
|
return message
|
1263
1263
|
|
1264
|
+
def _process_handle_message_result(
|
1265
|
+
self,
|
1266
|
+
msg: Any,
|
1267
|
+
orig_tool_name: str | None = None,
|
1268
|
+
chat_doc: Optional[ChatDocument] = None,
|
1269
|
+
) -> None | str | ChatDocument:
|
1270
|
+
"""
|
1271
|
+
Process result of agent_response or tool handler, or handle_message_fallback.
|
1272
|
+
"""
|
1273
|
+
if isinstance(msg, ToolMessage):
|
1274
|
+
# result is a ToolMessage, so...
|
1275
|
+
result_tool_name = msg.default_value("request")
|
1276
|
+
if result_tool_name in self.llm_tools_handled and (
|
1277
|
+
orig_tool_name is None or orig_tool_name != result_tool_name
|
1278
|
+
):
|
1279
|
+
# TODO: do we need to remove the tool message from the chat_doc?
|
1280
|
+
# if (chat_doc is not None and
|
1281
|
+
# msg in chat_doc.tool_messages):
|
1282
|
+
# chat_doc.tool_messages.remove(msg)
|
1283
|
+
# if we can handle it, do so
|
1284
|
+
result = self.handle_tool_message(msg, chat_doc=chat_doc)
|
1285
|
+
else:
|
1286
|
+
# else wrap it in an agent response and return it so
|
1287
|
+
# orchestrator can find a respondent
|
1288
|
+
result = self.create_agent_response(tool_messages=[msg])
|
1289
|
+
elif isinstance(msg, (ChatDocument, str)):
|
1290
|
+
result = msg
|
1291
|
+
elif isinstance(msg, BaseModel):
|
1292
|
+
result = msg.json()
|
1293
|
+
else:
|
1294
|
+
# last resort: use json.dumps() or str() to make it a str
|
1295
|
+
try:
|
1296
|
+
result = json.dumps(msg)
|
1297
|
+
except Exception:
|
1298
|
+
try:
|
1299
|
+
result = str(msg)
|
1300
|
+
except Exception as e:
|
1301
|
+
logger.error(
|
1302
|
+
f"""
|
1303
|
+
Error converting msg handler result to str: {e}",
|
1304
|
+
""",
|
1305
|
+
exc_info=True,
|
1306
|
+
)
|
1307
|
+
result = None
|
1308
|
+
return result
|
1309
|
+
|
1264
1310
|
def handle_tool_message(
|
1265
1311
|
self,
|
1266
1312
|
tool: ToolMessage,
|
@@ -1290,42 +1336,9 @@ class Agent(ABC):
|
|
1290
1336
|
maybe_result = handler_method(tool, chat_doc=chat_doc)
|
1291
1337
|
else:
|
1292
1338
|
maybe_result = handler_method(tool)
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
if (
|
1297
|
-
result_tool_name in self.llm_tools_handled
|
1298
|
-
and tool_name != result_tool_name
|
1299
|
-
):
|
1300
|
-
# TODO: do we need to remove the tool message from the chat_doc?
|
1301
|
-
# if (chat_doc is not None and
|
1302
|
-
# maybe_result in chat_doc.tool_messages):
|
1303
|
-
# chat_doc.tool_messages.remove(maybe_result)
|
1304
|
-
# if we can handle it, do so
|
1305
|
-
result = self.handle_tool_message(maybe_result, chat_doc=chat_doc)
|
1306
|
-
else:
|
1307
|
-
# else wrap it in an agent response and return it so
|
1308
|
-
# orchestrator can find a respondent
|
1309
|
-
result = self.create_agent_response(tool_messages=[maybe_result])
|
1310
|
-
elif isinstance(maybe_result, (ChatDocument, str)):
|
1311
|
-
result = maybe_result
|
1312
|
-
elif isinstance(maybe_result, BaseModel):
|
1313
|
-
result = maybe_result.json()
|
1314
|
-
else:
|
1315
|
-
# last resort: use json.dumps() or str() to make it a str
|
1316
|
-
try:
|
1317
|
-
result = json.dumps(maybe_result)
|
1318
|
-
except Exception:
|
1319
|
-
try:
|
1320
|
-
result = str(maybe_result)
|
1321
|
-
except Exception as e:
|
1322
|
-
logger.error(
|
1323
|
-
f"""
|
1324
|
-
Error converting result of {tool_name} to str: {e}",
|
1325
|
-
""",
|
1326
|
-
exc_info=True,
|
1327
|
-
)
|
1328
|
-
result = None
|
1339
|
+
result = self._process_handle_message_result(
|
1340
|
+
maybe_result, tool_name, chat_doc
|
1341
|
+
)
|
1329
1342
|
except Exception as e:
|
1330
1343
|
# raise the error here since we are sure it's
|
1331
1344
|
# not a pydantic validation error,
|
@@ -51,11 +51,13 @@ class LanceRAGTaskCreator:
|
|
51
51
|
critic_name=critic_name,
|
52
52
|
doc_agent_name=doc_agent_name,
|
53
53
|
doc_schema=agent._get_clean_vecdb_schema(),
|
54
|
+
llm=agent.config.llm,
|
54
55
|
)
|
55
56
|
query_plan_agent_config.set_system_message()
|
56
57
|
|
57
58
|
critic_config = QueryPlanCriticConfig(
|
58
59
|
doc_schema=agent._get_clean_vecdb_schema(),
|
60
|
+
llm=agent.config.llm,
|
59
61
|
)
|
60
62
|
critic_config.set_system_message()
|
61
63
|
|
langroid/agent/tool_message.py
CHANGED
@@ -296,6 +296,17 @@ class FinalResultTool(ToolMessage):
|
|
296
296
|
|
297
297
|
request: str = ""
|
298
298
|
purpose: str = "Ignored; Wrapper for a structured message"
|
299
|
+
id: str = "" # placeholder for OpenAI-API tool_call_id
|
300
|
+
|
301
|
+
_handle_only: bool = False # only allow handling, but not use (LLM-generation)?
|
299
302
|
|
300
303
|
class Config:
|
301
304
|
extra = Extra.allow
|
305
|
+
# only HANDLING allowed, NOT "use" (i.e LLM generation)
|
306
|
+
handle_only: bool = False
|
307
|
+
arbitrary_types_allowed = False
|
308
|
+
validate_all = True
|
309
|
+
validate_assignment = True
|
310
|
+
# do not include these fields in the generated schema
|
311
|
+
# since we don't require the LLM to specify them
|
312
|
+
schema_extra = {"exclude": {"purpose", "id"}}
|
langroid/parsing/code_parser.py
CHANGED
@@ -115,5 +115,7 @@ class CodeParser:
|
|
115
115
|
for d in docs
|
116
116
|
if d.metadata.language in self.config.extensions # type: ignore
|
117
117
|
]
|
118
|
+
if len(chunked_docs) == 0:
|
119
|
+
return []
|
118
120
|
# collapse the list of lists into a single list
|
119
121
|
return reduce(lambda x, y: x + y, chunked_docs)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
License: MIT
|
6
6
|
Author: Prasad Chalasani
|
@@ -162,6 +162,9 @@ into simplifying the developer experience; it does not use `Langchain`.
|
|
162
162
|
:fire: See this [Intro to Langroid](https://lancedb.substack.com/p/langoid-multi-agent-programming-framework)
|
163
163
|
blog post from the LanceDB team
|
164
164
|
|
165
|
+
:fire: Just published in ML for Healthcare (2024): a Langroid-based Multi-Agent RAG system for
|
166
|
+
pharmacovigilance, see [blog post](https://langroid.github.io/langroid/blog/2024/08/12/malade-multi-agent-architecture-for-pharmacovigilance/)
|
167
|
+
|
165
168
|
|
166
169
|
We welcome contributions -- See the [contributions](./CONTRIBUTING.md) document
|
167
170
|
for ideas on what to contribute.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
langroid/__init__.py,sha256=z_fCOLQJPOw3LLRPBlFB5-2HyCjpPgQa4m4iY5Fvb8Y,1800
|
2
2
|
langroid/agent/__init__.py,sha256=CFjjVvXVEV4ac0PdNPHVQHREV2HbbHCF6wj42v5MpJ4,826
|
3
|
-
langroid/agent/base.py,sha256=
|
3
|
+
langroid/agent/base.py,sha256=mb24KgKsNuX_7nvNHuTCQPcnsVV4-4PqC0EKV01qcqg,59232
|
4
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=Qedk1-CBCgo9PdaIa7AboLBFCTgAMg9q5nGmoqpZ378,22050
|
@@ -14,7 +14,7 @@ langroid/agent/special/doc_chat_agent.py,sha256=8NPAhMnHkFUolQ8EHos40tz5Vwuz_m33
|
|
14
14
|
langroid/agent/special/lance_doc_chat_agent.py,sha256=s8xoRs0gGaFtDYFUSIRchsgDVbS5Q3C2b2mr3V1Fd-Q,10419
|
15
15
|
langroid/agent/special/lance_rag/__init__.py,sha256=QTbs0IVE2ZgDg8JJy1zN97rUUg4uEPH7SLGctFNumk4,174
|
16
16
|
langroid/agent/special/lance_rag/critic_agent.py,sha256=lRHLBU9TWo4ixm_wEPUP9bCjW0iSIw7ZRe6u4D4v7jk,9519
|
17
|
-
langroid/agent/special/lance_rag/lance_rag_task.py,sha256=
|
17
|
+
langroid/agent/special/lance_rag/lance_rag_task.py,sha256=qDouwz-Yi8aSIAVb2Jx6buTKwO2L7PSvUY604Eu0uIM,2957
|
18
18
|
langroid/agent/special/lance_rag/query_planner_agent.py,sha256=-ZKareApPQD0EbwB1ABeZdhYAA2lJbwSVkfSuhMcKMk,11480
|
19
19
|
langroid/agent/special/lance_tools.py,sha256=qS8x4wi8mrqfbYV2ztFzrcxyhHQ0ZWOc-zkYiH7awj0,2105
|
20
20
|
langroid/agent/special/neo4j/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -34,7 +34,7 @@ langroid/agent/special/sql/utils/tools.py,sha256=vFYysk6Vi7HJjII8B4RitA3pt_z3gkS
|
|
34
34
|
langroid/agent/special/table_chat_agent.py,sha256=d9v2wsblaRx7oMnKhLV7uO_ujvk9gh59pSGvBXyeyNc,9659
|
35
35
|
langroid/agent/structured_message.py,sha256=y7pud1EgRNeTFZlJmBkLmwME3yQJ_IYik-Xds9kdZbY,282
|
36
36
|
langroid/agent/task.py,sha256=y4FXXLSJv_8LIox4-E48MG_VQl1558WCLR9w35-KBJ4,80560
|
37
|
-
langroid/agent/tool_message.py,sha256=
|
37
|
+
langroid/agent/tool_message.py,sha256=OiShCp8NwG7p3fVxwLhHCxhaRp2chuzEL7FBWOqoxg4,11715
|
38
38
|
langroid/agent/tools/__init__.py,sha256=lgWAWsPgMx-NdDPVX6tXO_U0cIQX7dwzhUC0G4IfUgk,726
|
39
39
|
langroid/agent/tools/duckduckgo_search_tool.py,sha256=NhsCaGZkdv28nja7yveAhSK_w6l_Ftym8agbrdzqgfo,1935
|
40
40
|
langroid/agent/tools/extract_tool.py,sha256=u5lL9rKBzaLBOrRyLnTAZ97pQ1uxyLP39XsWMnpaZpw,3789
|
@@ -82,7 +82,7 @@ langroid/mytypes.py,sha256=ptAFxEAtiwmIfUnGisNotTe8wT9LKBf22lOfPgZoQIY,2368
|
|
82
82
|
langroid/parsing/__init__.py,sha256=ZgSAfgTC6VsTLFlRSWT-TwYco7SQeRMeZG-49MnKYGY,936
|
83
83
|
langroid/parsing/agent_chats.py,sha256=sbZRV9ujdM5QXvvuHVjIi2ysYSYlap-uqfMMUKulrW0,1068
|
84
84
|
langroid/parsing/code-parsing.md,sha256=--cyyNiSZSDlIwcjAV4-shKrSiRe2ytF3AdSoS_hD2g,3294
|
85
|
-
langroid/parsing/code_parser.py,sha256=
|
85
|
+
langroid/parsing/code_parser.py,sha256=AOxb3xbYpTBPP3goOm5dKfJdh5hS_2BhLVCEkifWZN8,3796
|
86
86
|
langroid/parsing/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
87
87
|
langroid/parsing/document_parser.py,sha256=WGnA5ADwMHliGJt6WW9rc4RiFXQcKU33b5zdPiGrtEY,24265
|
88
88
|
langroid/parsing/image_text.py,sha256=sbLIQ5nHe2UnYUksBaQsmZGaX-X0qgEpPd7CEzi_z5M,910
|
@@ -134,8 +134,8 @@ langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3Hmh
|
|
134
134
|
langroid/vector_store/momento.py,sha256=qR-zBF1RKVHQZPZQYW_7g-XpTwr46p8HJuYPCkfJbM4,10534
|
135
135
|
langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
|
136
136
|
langroid/vector_store/qdrantdb.py,sha256=v88lqFkepADvlN6lByUj9I4NEKa9X9lWH16uTPPbYrE,17457
|
137
|
-
pyproject.toml,sha256=
|
138
|
-
langroid-0.10.
|
139
|
-
langroid-0.10.
|
140
|
-
langroid-0.10.
|
141
|
-
langroid-0.10.
|
137
|
+
pyproject.toml,sha256=21iGX12213VuyH8F3VPPMSnMQVCozYwNpBrpESXVN70,7088
|
138
|
+
langroid-0.10.1.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
139
|
+
langroid-0.10.1.dist-info/METADATA,sha256=0KuuhuEIzCzwo1ySmkGGL6pepOTwBADkmVR6NNzh9Pg,54992
|
140
|
+
langroid-0.10.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
141
|
+
langroid-0.10.1.dist-info/RECORD,,
|
pyproject.toml
CHANGED
File without changes
|
File without changes
|