fyodorov-llm-agents 0.4.5__py3-none-any.whl → 0.4.7__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.
@@ -3,7 +3,7 @@ import re
3
3
  from pydantic import BaseModel, HttpUrl
4
4
  from typing import Optional
5
5
  import litellm
6
- # from fyodorov_llm_agents.tools.mcp_tool_service import MCPTool as ToolService
6
+ from fyodorov_llm_agents.tools.mcp_tool_service import MCPTool as ToolService
7
7
  from datetime import datetime
8
8
 
9
9
  MAX_NAME_LENGTH = 80
@@ -72,7 +72,7 @@ class Agent(BaseModel):
72
72
  # 'rag': self.rag,
73
73
  # }
74
74
 
75
- def call_with_fn_calling(self, input: str = "", history = []) -> dict:
75
+ def call_with_fn_calling(self, input: str = "", history = [], user_id: str = "") -> dict:
76
76
  litellm.set_verbose = True
77
77
  model = self.model
78
78
  # Set environmental variable
@@ -96,12 +96,59 @@ class Agent(BaseModel):
96
96
  *history,
97
97
  { "content": input, "role": "user"},
98
98
  ]
99
- print(f"Tools: {self.tools}")
100
99
  # tools
101
- print(f"calling litellm with model {model}, messages: {messages}, max_retries: 0, history: {history}, base_url: {base_url}")
102
- response = litellm.completion(model=model, messages=messages, max_retries=0, base_url=base_url)
100
+ print(f"Tools: {self.tools}")
101
+ mcp_tools = []
102
+ for tool in self.tools:
103
+ try:
104
+ tool_instance = ToolService.get_by_name_and_user_id(tool, user_id)
105
+ mcp_tools.append(tool_instance)
106
+ except Exception as e:
107
+ print(f"Error fetching tool {tool}: {e}")
108
+
109
+ tool_schemas = [tool.get_function() for tool in mcp_tools]
110
+ print(f"Tool schemas: {tool_schemas}")
111
+ if tool_schemas:
112
+ print(f"calling litellm with model {model}, messages: {messages}, max_retries: 0, history: {history}, base_url: {base_url}, tools: {tool_schemas}")
113
+ response = litellm.completion(model=model, messages=messages, max_retries=0, base_url=base_url)
114
+ else:
115
+ print(f"calling litellm with model {model}, messages: {messages}, max_retries: 0, history: {history}, base_url: {base_url}")
116
+ response = litellm.completion(model=model, messages=messages, max_retries=0, base_url=base_url)
103
117
  print(f"Response: {response}")
104
- answer = response.choices[0].message.content
118
+
119
+ message = response.choices[0].message
120
+
121
+ if hasattr(message, "tool_calls") and message.tool_calls:
122
+ tool_call = message.tool_calls[0]
123
+ fn_name = tool_call.function.name
124
+ args = tool_call.function.arguments
125
+
126
+ mcp_tool = mcp_tools.get(fn_name)
127
+ if not mcp_tool:
128
+ raise ValueError(f"Tool '{fn_name}' not found in loaded MCP tools")
129
+
130
+ tool_output = mcp_tool.call(args)
131
+
132
+ messages.append({
133
+ "role": "assistant",
134
+ "content": None,
135
+ "tool_calls": [tool_call],
136
+ })
137
+ messages.append({
138
+ "role": "tool",
139
+ "tool_call_id": tool_call.id,
140
+ "content": tool_output,
141
+ })
142
+
143
+ followup = litellm.completion(
144
+ model=model,
145
+ messages=messages,
146
+ max_retries=0,
147
+ base_url=base_url,
148
+ )
149
+ return {"answer": followup.choices[0].message.content}
150
+
151
+ answer = message.content
105
152
  print(f"Answer: {answer}")
106
153
  return {
107
154
  "answer": answer,
@@ -30,7 +30,7 @@ class Instance(InstanceModel):
30
30
  # if isinstance(tool, str):
31
31
  # agent.tools[index] = Tool.get_by_name_and_user_id(access_token, tool, user_id)
32
32
  # print(f"Tool fetched via Tool.get_by_name_and_user_id in chat_w_fn_calls: {agent.tools[index]}")
33
- res = agent.call_with_fn_calling(input=input, history=self.chat_history)
33
+ res = agent.call_with_fn_calling(input=input, history=self.chat_history, user_id=user_id)
34
34
  self.chat_history.append({
35
35
  "role": "user",
36
36
  "content": input
@@ -1,8 +1,8 @@
1
1
  from datetime import datetime
2
- from .llm_model import LLMModel
3
- from .provider import Provider
4
2
  from supabase import Client
5
3
  from fyodorov_utils.config.supabase import get_supabase
4
+ from fyodorov_llm_agents.providers.provider_service import Provider
5
+ from fyodorov_llm_agents.models.llm_model import LLMModel
6
6
 
7
7
  supabase: Client = get_supabase()
8
8
 
@@ -73,6 +73,21 @@ class MCPTool(BaseModel):
73
73
  tool.validate()
74
74
  return tool
75
75
 
76
+ def get_function(self) -> dict:
77
+ """
78
+ Convert this MCP tool into a function definition usable by LLMs (OpenAI-style).
79
+ """
80
+ if not self.capabilities or "functions" not in self.capabilities:
81
+ raise ValueError(f"Tool '{self.name}' is missing `capabilities.functions`")
82
+
83
+ # For now: return the first declared capability
84
+ func = self.capabilities["functions"][0]
85
+ return {
86
+ "name": func["name"],
87
+ "description": func.get("description", "No description provided."),
88
+ "parameters": func.get("parameters", {}),
89
+ }
90
+
76
91
  def call(self, args: dict) -> str:
77
92
  if not self.api_url:
78
93
  raise ValueError("MCP tool is missing an `api_url`")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fyodorov_llm_agents
3
- Version: 0.4.5
3
+ Version: 0.4.7
4
4
  Summary: LLM agents for the Fyodorov AI suite
5
5
  Author-email: Daniel Ransom <02masseur.alibis@icloud.com>
6
6
  Project-URL: Homepage, https://github.com/FyodorovAI/fyodorov-llm-agents
@@ -1,16 +1,16 @@
1
- fyodorov_llm_agents/agents/agent_model.py,sha256=vVBCEBpG11m4ae11Mr94rF5TJpuBluI_loQPDTw734w,5044
1
+ fyodorov_llm_agents/agents/agent_model.py,sha256=LxoQ8ZrGt_xYbcAjFTZC4ff8zvzsWq9MstTmroFBTdE,6827
2
2
  fyodorov_llm_agents/agents/agent_service.py,sha256=-55RDait3eZGFfYWGNLGoa06WMcdiBnkzpa7BnWW10Q,6016
3
3
  fyodorov_llm_agents/agents/openai.py,sha256=FA5RS7yn3JwvFA8PXju60XSYC_2oUZFNgBUzeIYtGv0,1154
4
4
  fyodorov_llm_agents/instances/instance_model.py,sha256=PQaoVSH9H4qp_wcLvyT_QgvNtwf9oehOxZaGI6mv1bA,1206
5
- fyodorov_llm_agents/instances/instance_service.py,sha256=8tXWimECQd0Ks5Q9j2S2wvfJd7j9CPvLG6tLmdzGqXg,8281
5
+ fyodorov_llm_agents/instances/instance_service.py,sha256=oytsWHR2-OUiALwPN6wSkHadoEiUJVU3_gwvi8Y_ghM,8298
6
6
  fyodorov_llm_agents/models/llm_model.py,sha256=aQtXtB7kRpnVdbPu-nmTGAaflbtKz3DPkgcckf1srsg,1645
7
- fyodorov_llm_agents/models/llm_service.py,sha256=ifSyznv9MY2kyRALClM-epdCQ9abMgsoDanS8TN0Nng,3945
7
+ fyodorov_llm_agents/models/llm_service.py,sha256=35bS0RFXJhJUSjge-v4u5cftn_MT-CmcDuWnC2kCnJo,4008
8
8
  fyodorov_llm_agents/providers/provider_model.py,sha256=OyCK6WMRhyElsp88gILg0wso-OPHI7f55gEeypsJ7O0,957
9
9
  fyodorov_llm_agents/providers/provider_service.py,sha256=GST-NLV8aLPsvapQEvgT_qHGYu7IpS5Xsut60XFmD-g,5865
10
- fyodorov_llm_agents/tools/mcp_tool_model.py,sha256=i7oFZReVGZsHN2K8T7mCAGF4t92wMMIR9mCkRHUgKsI,4413
10
+ fyodorov_llm_agents/tools/mcp_tool_model.py,sha256=LuQE-mu5zKmiMmWOOKETAVkjwGsHSbcDbB57piEAACU,5025
11
11
  fyodorov_llm_agents/tools/mcp_tool_service.py,sha256=9tDvSdKpEAOKKU5MHImUqTOc6MZyk1hEjs3GpzgQUsk,5542
12
12
  fyodorov_llm_agents/tools/tool.py,sha256=HyOk0X_3XE23sa8J-8UZx657tJ0sxwZWMbA4OPxXU6E,7940
13
- fyodorov_llm_agents-0.4.5.dist-info/METADATA,sha256=41-LenOznx7t3sFfTACSBQ9Mi12jPYIXeT1dedOnUa4,550
14
- fyodorov_llm_agents-0.4.5.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
15
- fyodorov_llm_agents-0.4.5.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
16
- fyodorov_llm_agents-0.4.5.dist-info/RECORD,,
13
+ fyodorov_llm_agents-0.4.7.dist-info/METADATA,sha256=d724yOM7r0XyfRw0QZZAyEcUbuRu1N-ww6td4ZMjxH8,550
14
+ fyodorov_llm_agents-0.4.7.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
15
+ fyodorov_llm_agents-0.4.7.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
16
+ fyodorov_llm_agents-0.4.7.dist-info/RECORD,,