praisonaiagents 0.0.67__py3-none-any.whl → 0.0.68__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.
- praisonaiagents/agent/agent.py +89 -19
- praisonaiagents/llm/llm.py +10 -4
- praisonaiagents/mcp/mcp.py +39 -0
- {praisonaiagents-0.0.67.dist-info → praisonaiagents-0.0.68.dist-info}/METADATA +2 -1
- {praisonaiagents-0.0.67.dist-info → praisonaiagents-0.0.68.dist-info}/RECORD +7 -7
- {praisonaiagents-0.0.67.dist-info → praisonaiagents-0.0.68.dist-info}/WHEEL +0 -0
- {praisonaiagents-0.0.67.dist-info → praisonaiagents-0.0.68.dist-info}/top_level.txt +0 -0
praisonaiagents/agent/agent.py
CHANGED
@@ -421,6 +421,12 @@ class Agent:
|
|
421
421
|
# Pass the entire string so LiteLLM can parse provider/model
|
422
422
|
self.llm_instance = LLM(model=llm)
|
423
423
|
self._using_custom_llm = True
|
424
|
+
|
425
|
+
# Ensure tools are properly accessible when using custom LLM
|
426
|
+
if tools:
|
427
|
+
logging.debug(f"Tools passed to Agent with custom LLM: {tools}")
|
428
|
+
# Store the tools for later use
|
429
|
+
self.tools = tools
|
424
430
|
except ImportError as e:
|
425
431
|
raise ImportError(
|
426
432
|
"LLM features requested but dependencies not installed. "
|
@@ -519,9 +525,20 @@ Your Goal: {self.goal}
|
|
519
525
|
"""
|
520
526
|
logging.debug(f"{self.name} executing tool {function_name} with arguments: {arguments}")
|
521
527
|
|
528
|
+
# Special handling for MCP tools
|
529
|
+
# Check if tools is an MCP instance with the requested function name
|
530
|
+
from ..mcp.mcp import MCP
|
531
|
+
if isinstance(self.tools, MCP):
|
532
|
+
logging.debug(f"Looking for MCP tool {function_name}")
|
533
|
+
# Check if any of the MCP tools match the function name
|
534
|
+
for mcp_tool in self.tools.runner.tools:
|
535
|
+
if hasattr(mcp_tool, 'name') and mcp_tool.name == function_name:
|
536
|
+
logging.debug(f"Found matching MCP tool: {function_name}")
|
537
|
+
return self.tools.runner.call_tool(function_name, arguments)
|
538
|
+
|
522
539
|
# Try to find the function in the agent's tools list first
|
523
540
|
func = None
|
524
|
-
for tool in self.tools:
|
541
|
+
for tool in self.tools if isinstance(self.tools, (list, tuple)) else []:
|
525
542
|
if (callable(tool) and getattr(tool, '__name__', '') == function_name) or \
|
526
543
|
(inspect.isclass(tool) and tool.__name__ == function_name):
|
527
544
|
func = tool
|
@@ -643,24 +660,64 @@ Your Goal: {self.goal}
|
|
643
660
|
logging.warning(f"Tool {tool} not recognized")
|
644
661
|
|
645
662
|
try:
|
646
|
-
if
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
663
|
+
# Use the custom LLM instance if available
|
664
|
+
if self._using_custom_llm and hasattr(self, 'llm_instance'):
|
665
|
+
if stream:
|
666
|
+
# Debug logs for tool info
|
667
|
+
if formatted_tools:
|
668
|
+
logging.debug(f"Passing {len(formatted_tools)} formatted tools to LLM instance: {formatted_tools}")
|
669
|
+
|
670
|
+
# Use the LLM instance for streaming responses
|
671
|
+
final_response = self.llm_instance.get_response(
|
672
|
+
prompt=messages[1:], # Skip system message as LLM handles it separately
|
673
|
+
system_prompt=messages[0]['content'] if messages and messages[0]['role'] == 'system' else None,
|
674
|
+
temperature=temperature,
|
675
|
+
tools=formatted_tools if formatted_tools else None,
|
676
|
+
verbose=self.verbose,
|
677
|
+
markdown=self.markdown,
|
678
|
+
stream=True,
|
679
|
+
console=self.console,
|
680
|
+
execute_tool_fn=self.execute_tool,
|
681
|
+
agent_name=self.name,
|
682
|
+
agent_role=self.role,
|
683
|
+
reasoning_steps=reasoning_steps
|
684
|
+
)
|
685
|
+
else:
|
686
|
+
# Non-streaming with custom LLM
|
687
|
+
final_response = self.llm_instance.get_response(
|
688
|
+
prompt=messages[1:],
|
689
|
+
system_prompt=messages[0]['content'] if messages and messages[0]['role'] == 'system' else None,
|
690
|
+
temperature=temperature,
|
691
|
+
tools=formatted_tools if formatted_tools else None,
|
692
|
+
verbose=self.verbose,
|
693
|
+
markdown=self.markdown,
|
694
|
+
stream=False,
|
695
|
+
console=self.console,
|
696
|
+
execute_tool_fn=self.execute_tool,
|
697
|
+
agent_name=self.name,
|
698
|
+
agent_role=self.role,
|
699
|
+
reasoning_steps=reasoning_steps
|
700
|
+
)
|
655
701
|
else:
|
656
|
-
#
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
702
|
+
# Use the standard OpenAI client approach
|
703
|
+
if stream:
|
704
|
+
# Process as streaming response with formatted tools
|
705
|
+
final_response = self._process_stream_response(
|
706
|
+
messages,
|
707
|
+
temperature,
|
708
|
+
start_time,
|
709
|
+
formatted_tools=formatted_tools if formatted_tools else None,
|
710
|
+
reasoning_steps=reasoning_steps
|
711
|
+
)
|
712
|
+
else:
|
713
|
+
# Process as regular non-streaming response
|
714
|
+
final_response = client.chat.completions.create(
|
715
|
+
model=self.llm,
|
716
|
+
messages=messages,
|
717
|
+
temperature=temperature,
|
718
|
+
tools=formatted_tools if formatted_tools else None,
|
719
|
+
stream=False
|
720
|
+
)
|
664
721
|
|
665
722
|
tool_calls = getattr(final_response.choices[0].message, 'tool_calls', None)
|
666
723
|
|
@@ -748,13 +805,26 @@ Your Goal: {self.goal}
|
|
748
805
|
|
749
806
|
if self._using_custom_llm:
|
750
807
|
try:
|
808
|
+
# Special handling for MCP tools when using provider/model format
|
809
|
+
tool_param = self.tools if tools is None else tools
|
810
|
+
|
811
|
+
# Convert MCP tool objects to OpenAI format if needed
|
812
|
+
if tool_param is not None:
|
813
|
+
from ..mcp.mcp import MCP
|
814
|
+
if isinstance(tool_param, MCP) and hasattr(tool_param, 'to_openai_tool'):
|
815
|
+
logging.debug("Converting MCP tool to OpenAI format")
|
816
|
+
openai_tool = tool_param.to_openai_tool()
|
817
|
+
if openai_tool:
|
818
|
+
tool_param = [openai_tool]
|
819
|
+
logging.debug(f"Converted MCP tool: {tool_param}")
|
820
|
+
|
751
821
|
# Pass everything to LLM class
|
752
822
|
response_text = self.llm_instance.get_response(
|
753
823
|
prompt=prompt,
|
754
824
|
system_prompt=f"{self.backstory}\n\nYour Role: {self.role}\n\nYour Goal: {self.goal}" if self.use_system_prompt else None,
|
755
825
|
chat_history=self.chat_history,
|
756
826
|
temperature=temperature,
|
757
|
-
tools=
|
827
|
+
tools=tool_param,
|
758
828
|
output_json=output_json,
|
759
829
|
output_pydantic=output_pydantic,
|
760
830
|
verbose=self.verbose,
|
praisonaiagents/llm/llm.py
CHANGED
@@ -289,15 +289,21 @@ class LLM:
|
|
289
289
|
if tools:
|
290
290
|
formatted_tools = []
|
291
291
|
for tool in tools:
|
292
|
-
if
|
292
|
+
# Check if the tool is already in OpenAI format (e.g. from MCP.to_openai_tool())
|
293
|
+
if isinstance(tool, dict) and 'type' in tool and tool['type'] == 'function':
|
294
|
+
logging.debug(f"Using pre-formatted OpenAI tool: {tool['function']['name']}")
|
295
|
+
formatted_tools.append(tool)
|
296
|
+
elif callable(tool):
|
293
297
|
tool_def = self._generate_tool_definition(tool.__name__)
|
298
|
+
if tool_def:
|
299
|
+
formatted_tools.append(tool_def)
|
294
300
|
elif isinstance(tool, str):
|
295
301
|
tool_def = self._generate_tool_definition(tool)
|
302
|
+
if tool_def:
|
303
|
+
formatted_tools.append(tool_def)
|
296
304
|
else:
|
297
|
-
|
305
|
+
logging.debug(f"Skipping tool of unsupported type: {type(tool)}")
|
298
306
|
|
299
|
-
if tool_def:
|
300
|
-
formatted_tools.append(tool_def)
|
301
307
|
if not formatted_tools:
|
302
308
|
formatted_tools = None
|
303
309
|
|
praisonaiagents/mcp/mcp.py
CHANGED
@@ -313,6 +313,45 @@ class MCP:
|
|
313
313
|
"""
|
314
314
|
return iter(self._tools)
|
315
315
|
|
316
|
+
def to_openai_tool(self):
|
317
|
+
"""Convert the MCP tool to an OpenAI-compatible tool definition.
|
318
|
+
|
319
|
+
This method is specifically invoked by the Agent class when using
|
320
|
+
provider/model format (e.g., "openai/gpt-4o-mini").
|
321
|
+
|
322
|
+
Returns:
|
323
|
+
dict: OpenAI-compatible tool definition
|
324
|
+
"""
|
325
|
+
# For simplicity, we'll convert the first tool only if multiple exist
|
326
|
+
# More complex implementations could handle multiple tools
|
327
|
+
if not self.runner.tools:
|
328
|
+
logging.warning("No MCP tools available to convert to OpenAI format")
|
329
|
+
return None
|
330
|
+
|
331
|
+
# Get the first tool's schema
|
332
|
+
tool = self.runner.tools[0]
|
333
|
+
|
334
|
+
# Create OpenAI tool definition
|
335
|
+
parameters = {}
|
336
|
+
if hasattr(tool, 'inputSchema') and tool.inputSchema:
|
337
|
+
parameters = tool.inputSchema
|
338
|
+
else:
|
339
|
+
# Create a minimal schema if none exists
|
340
|
+
parameters = {
|
341
|
+
"type": "object",
|
342
|
+
"properties": {},
|
343
|
+
"required": []
|
344
|
+
}
|
345
|
+
|
346
|
+
return {
|
347
|
+
"type": "function",
|
348
|
+
"function": {
|
349
|
+
"name": tool.name,
|
350
|
+
"description": tool.description if hasattr(tool, 'description') else f"Call the {tool.name} tool",
|
351
|
+
"parameters": parameters
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
316
355
|
def __del__(self):
|
317
356
|
"""Clean up resources when the object is garbage collected."""
|
318
357
|
if hasattr(self, 'runner'):
|
@@ -1,11 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: praisonaiagents
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.68
|
4
4
|
Summary: Praison AI agents for completing complex tasks with Self Reflection Agents
|
5
5
|
Author: Mervin Praison
|
6
6
|
Requires-Dist: pydantic
|
7
7
|
Requires-Dist: rich
|
8
8
|
Requires-Dist: openai
|
9
|
+
Requires-Dist: mcp==1.6.0
|
9
10
|
Provides-Extra: memory
|
10
11
|
Requires-Dist: chromadb>=0.5.23; extra == "memory"
|
11
12
|
Provides-Extra: knowledge
|
@@ -1,7 +1,7 @@
|
|
1
1
|
praisonaiagents/__init__.py,sha256=Z2_rSA6mYozz0r3ioUgKzl3QV8uWRDS_QaqPg2oGjqg,1324
|
2
2
|
praisonaiagents/main.py,sha256=l29nGEbV2ReBi4szURbnH0Fk0w2F_QZTmECysyZjYcA,15066
|
3
3
|
praisonaiagents/agent/__init__.py,sha256=j0T19TVNbfZcClvpbZDDinQxZ0oORgsMrMqx16jZ-bA,128
|
4
|
-
praisonaiagents/agent/agent.py,sha256=
|
4
|
+
praisonaiagents/agent/agent.py,sha256=NiTUqkibCKW6Rx0HbR1peY3TtOcQl2O8XdrEV__gPlM,65805
|
5
5
|
praisonaiagents/agent/image_agent.py,sha256=-5MXG594HVwSpFMcidt16YBp7udtik-Cp7eXlzLE1fY,8696
|
6
6
|
praisonaiagents/agents/__init__.py,sha256=_1d6Pqyk9EoBSo7E68sKyd1jDRlN1vxvVIRpoMc0Jcw,168
|
7
7
|
praisonaiagents/agents/agents.py,sha256=KLfSuz6nGEJM-n4xCXdtIkES6cUI-LwvMxI3R-MjrD0,37862
|
@@ -10,9 +10,9 @@ praisonaiagents/knowledge/__init__.py,sha256=xL1Eh-a3xsHyIcU4foOWF-JdWYIYBALJH9b
|
|
10
10
|
praisonaiagents/knowledge/chunking.py,sha256=FzoNY0q8MkvG4gADqk4JcRhmH3lcEHbRdonDgitQa30,6624
|
11
11
|
praisonaiagents/knowledge/knowledge.py,sha256=fQNREDiwdoisfIxJBLVkteXgq_8Gbypfc3UaZbxf5QY,13210
|
12
12
|
praisonaiagents/llm/__init__.py,sha256=ttPQQJQq6Tah-0updoEXDZFKWtJAM93rBWRoIgxRWO8,689
|
13
|
-
praisonaiagents/llm/llm.py,sha256=
|
13
|
+
praisonaiagents/llm/llm.py,sha256=l7Z2QjD9eFy0Zq5bwTVK7VOUHxeTyx866YWt3fS3vz8,74606
|
14
14
|
praisonaiagents/mcp/__init__.py,sha256=IkYdrAK1bDQDm_0t3Wjt63Zwv3_IJgqz84Wqz9GH2iQ,111
|
15
|
-
praisonaiagents/mcp/mcp.py,sha256=
|
15
|
+
praisonaiagents/mcp/mcp.py,sha256=BPPf5AIPXx28PaJJqOg6T3NRyymQH9YAD-Km7Ma9-KA,13681
|
16
16
|
praisonaiagents/memory/memory.py,sha256=I8dOTkrl1i-GgQbDcrFOsSruzJ7MiI6Ys37DK27wrUs,35537
|
17
17
|
praisonaiagents/process/__init__.py,sha256=lkYbL7Hn5a0ldvJtkdH23vfIIZLIcanK-65C0MwaorY,52
|
18
18
|
praisonaiagents/process/process.py,sha256=HPw84OhnKQW3EyrDkpoQu0DcpxThbrzR2hWUgwQh9Pw,59955
|
@@ -39,7 +39,7 @@ praisonaiagents/tools/xml_tools.py,sha256=iYTMBEk5l3L3ryQ1fkUnNVYK-Nnua2Kx2S0dxN
|
|
39
39
|
praisonaiagents/tools/yaml_tools.py,sha256=uogAZrhXV9O7xvspAtcTfpKSQYL2nlOTvCQXN94-G9A,14215
|
40
40
|
praisonaiagents/tools/yfinance_tools.py,sha256=s2PBj_1v7oQnOobo2fDbQBACEHl61ftG4beG6Z979ZE,8529
|
41
41
|
praisonaiagents/tools/train/data/generatecot.py,sha256=H6bNh-E2hqL5MW6kX3hqZ05g9ETKN2-kudSjiuU_SD8,19403
|
42
|
-
praisonaiagents-0.0.
|
43
|
-
praisonaiagents-0.0.
|
44
|
-
praisonaiagents-0.0.
|
45
|
-
praisonaiagents-0.0.
|
42
|
+
praisonaiagents-0.0.68.dist-info/METADATA,sha256=wMy9WDu6aGcQWrQIFT1UMOfB-wcvrGqpeDwXqbQXIvM,856
|
43
|
+
praisonaiagents-0.0.68.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
44
|
+
praisonaiagents-0.0.68.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
|
45
|
+
praisonaiagents-0.0.68.dist-info/RECORD,,
|
File without changes
|
File without changes
|