fyodorov-llm-agents 0.3.6__py3-none-any.whl → 0.3.8__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.
- fyodorov_llm_agents/agents/agent.py +1 -39
- fyodorov_llm_agents/instances/instance.py +163 -0
- {fyodorov_llm_agents-0.3.6.dist-info → fyodorov_llm_agents-0.3.8.dist-info}/METADATA +1 -1
- fyodorov_llm_agents-0.3.8.dist-info/RECORD +10 -0
- fyodorov_llm_agents-0.3.6.dist-info/RECORD +0 -9
- {fyodorov_llm_agents-0.3.6.dist-info → fyodorov_llm_agents-0.3.8.dist-info}/WHEEL +0 -0
- {fyodorov_llm_agents-0.3.6.dist-info → fyodorov_llm_agents-0.3.8.dist-info}/top_level.txt +0 -0
@@ -72,50 +72,12 @@ class Agent(BaseModel):
|
|
72
72
|
# 'rag': self.rag,
|
73
73
|
# }
|
74
74
|
|
75
|
-
def call_with_fn_calling_old(self, input: str = "", history = []) -> dict:
|
76
|
-
litellm.set_verbose = True
|
77
|
-
model = self.model
|
78
|
-
# Set environmental variable
|
79
|
-
if self.api_key.startswith('sk-'):
|
80
|
-
model = 'openai/'+self.model
|
81
|
-
os.environ["OPENAI_API_KEY"] = self.api_key
|
82
|
-
self.api_url = "https://api.openai.com/v1"
|
83
|
-
elif self.api_key and self.api_key != '':
|
84
|
-
model = 'mistral/'+self.model
|
85
|
-
os.environ["MISTRAL_API_KEY"] = self.api_key
|
86
|
-
self.api_url = "https://api.mistral.ai/v1"
|
87
|
-
else:
|
88
|
-
print("Provider Ollama")
|
89
|
-
model = 'ollama/'+self.model
|
90
|
-
if self.api_url is None:
|
91
|
-
self.api_url = "https://api.ollama.ai/v1"
|
92
|
-
|
93
|
-
base_url = str(self.api_url)
|
94
|
-
if base_url and base_url[-1] == '/':
|
95
|
-
print("Removing trailing slash")
|
96
|
-
base_url = base_url[:-1]
|
97
|
-
|
98
|
-
messages: [] = [
|
99
|
-
{"content": self.prompt, "role": "system"},
|
100
|
-
*history,
|
101
|
-
{ "content": input, "role": "user"},
|
102
|
-
]
|
103
|
-
print(f"Tools: {self.tools}")
|
104
|
-
print(f"calling litellm with model {model}, messages: {messages}, max_retries: 0, history: {history}, base_url: {base_url}")
|
105
|
-
response = litellm.completion(model=model, messages=messages, max_retries=0, base_url=base_url)
|
106
|
-
print(f"Response: {response}")
|
107
|
-
answer = response.choices[0].message.content
|
108
|
-
print(f"Answer: {answer}")
|
109
|
-
return {
|
110
|
-
"answer": answer,
|
111
|
-
|
112
|
-
}
|
113
|
-
|
114
75
|
def call_with_fn_calling(self, input: str = "", history = []) -> dict:
|
115
76
|
litellm.set_verbose = True
|
116
77
|
model = self.model
|
117
78
|
# Set environmental variable
|
118
79
|
if self.api_key.startswith('sk-'):
|
80
|
+
model = 'openai/'+self.model
|
119
81
|
os.environ["OPENAI_API_KEY"] = self.api_key
|
120
82
|
self.api_url = "https://api.openai.com/v1"
|
121
83
|
elif self.api_key and self.api_key != '':
|
@@ -0,0 +1,163 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from supabase import Client
|
3
|
+
from fyodorov_utils.config.supabase import get_supabase
|
4
|
+
from models.instance import InstanceModel
|
5
|
+
from fyodorov_llm_agents.agents.agent import Agent as AgentModel
|
6
|
+
from .agent import Agent
|
7
|
+
from .provider import Provider
|
8
|
+
|
9
|
+
from fyodorov_llm_agents.tools.mcp_tool_service import MCPTool as Tool
|
10
|
+
from .model import LLM
|
11
|
+
from models.model import LLMModel
|
12
|
+
|
13
|
+
supabase: Client = get_supabase()
|
14
|
+
|
15
|
+
JWT = "eyJhbGciOiJIUzI1NiIsImtpZCI6Im14MmVrTllBY3ZYN292LzMiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzA3MzI0MTMxLCJpYXQiOjE3MDczMjA1MzEsImlzcyI6Imh0dHBzOi8vbGptd2R2ZWZrZ3l4cnVjc2dla3cuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6IjljYzYzOWQ0LWUwMzItNDM3Zi1hNWVhLTUzNDljZGE0YTNmZCIsImVtYWlsIjoiZGFuaWVsQGRhbmllbHJhbnNvbS5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7Imludml0ZV9jb2RlIjoiUkFOU09NIn0sInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiYWFsIjoiYWFsMSIsImFtciI6W3sibWV0aG9kIjoicGFzc3dvcmQiLCJ0aW1lc3RhbXAiOjE3MDczMjA1MzF9XSwic2Vzc2lvbl9pZCI6ImE4MTM4NmE1LTUxZTUtNDkyMS04ZjM3LWMyYWE3ODlhZDRhZiJ9.NNZA2rm1IQQ9wAhpyC8taMqregRmy8I9oZgT0P5heBg"
|
16
|
+
|
17
|
+
class Instance(InstanceModel):
|
18
|
+
|
19
|
+
async def chat_w_fn_calls(self, input: str = "", access_token: str = JWT, user_id: str = "") -> str:
|
20
|
+
agent: AgentModel = await Agent.get_in_db(access_token=access_token, id = self.agent_id)
|
21
|
+
model: LLMModel = await LLM.get_model(access_token, user_id, id = agent.modelid)
|
22
|
+
print(f"Model fetched via LLM.get_model in chat_w_fn_calls: {model}")
|
23
|
+
provider: Provider = await Provider.get_provider_by_id(access_token, id = model.provider)
|
24
|
+
prompt = f"{agent.prompt}\n\n{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
25
|
+
agent.prompt = prompt
|
26
|
+
agent.model = model.base_model
|
27
|
+
agent.api_key = provider.api_key
|
28
|
+
agent.api_url = provider.api_url
|
29
|
+
# for index, tool in enumerate(agent.tools):
|
30
|
+
# if isinstance(tool, str):
|
31
|
+
# agent.tools[index] = Tool.get_by_name_and_user_id(access_token, tool, user_id)
|
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)
|
34
|
+
self.chat_history.append({
|
35
|
+
"role": "user",
|
36
|
+
"content": input
|
37
|
+
})
|
38
|
+
self.chat_history.append({
|
39
|
+
"role": "assistant",
|
40
|
+
"content": res["answer"]
|
41
|
+
})
|
42
|
+
# Update history
|
43
|
+
await self.create_in_db(instance=self)
|
44
|
+
return res
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
async def create_in_db(instance: InstanceModel) -> dict:
|
48
|
+
try:
|
49
|
+
existing_instance = Instance.get_by_title_and_agent(instance.title, instance.agent_id)
|
50
|
+
if existing_instance:
|
51
|
+
needs_update = False
|
52
|
+
for key, value in instance.to_dict().items():
|
53
|
+
if value != existing_instance[key]:
|
54
|
+
print(f"Instance {key} needs updating: {value} != {existing_instance[key]}")
|
55
|
+
needs_update = True
|
56
|
+
existing_instance[key] = value
|
57
|
+
if needs_update:
|
58
|
+
print('Instance already exists, will update:', existing_instance)
|
59
|
+
instance_dict = await Instance.update_in_db(existing_instance["id"], existing_instance)
|
60
|
+
else:
|
61
|
+
print('Instance already exists and no update needed:', existing_instance)
|
62
|
+
instance_dict = existing_instance
|
63
|
+
else:
|
64
|
+
print("Creating instance in DB:", instance.to_dict())
|
65
|
+
result = supabase.table('instances').upsert(instance.to_dict()).execute()
|
66
|
+
if not result or not result.data:
|
67
|
+
print(f"Error creating instance in DB: {result}")
|
68
|
+
raise ValueError('Error creating instance in DB')
|
69
|
+
print(f"Result of creating instance in DB: {result}")
|
70
|
+
instance_dict = result.data[0]
|
71
|
+
instance_dict["id"] = str(instance_dict["id"])
|
72
|
+
instance_dict["agent_id"] = str(instance_dict["agent_id"])
|
73
|
+
return instance_dict
|
74
|
+
except Exception as e:
|
75
|
+
print(f"An error occurred while creating instance: {e}")
|
76
|
+
if 'code' in e and e.code == '23505':
|
77
|
+
print('Instance already exists')
|
78
|
+
instance_dict = Instance.get_by_title_and_agent(instance.title, instance.agent_id)
|
79
|
+
return instance_dict
|
80
|
+
print('Error creating instance', str(e))
|
81
|
+
raise e
|
82
|
+
|
83
|
+
@staticmethod
|
84
|
+
async def update_in_db(id: str, instance: dict) -> InstanceModel:
|
85
|
+
if not id:
|
86
|
+
raise ValueError('Instance ID is required')
|
87
|
+
try:
|
88
|
+
print(f"Updating instance in DB with ID: {id}, data: {instance}")
|
89
|
+
result = supabase.table('instances').update(instance).eq('id', id).execute()
|
90
|
+
print(f"Result of update: {result}")
|
91
|
+
instance_dict = result.data[0]
|
92
|
+
instance_dict["id"] = str(instance_dict["id"])
|
93
|
+
return instance_dict
|
94
|
+
except Exception as e:
|
95
|
+
print('An error occurred while updating instance:', id, str(e))
|
96
|
+
raise
|
97
|
+
|
98
|
+
@staticmethod
|
99
|
+
async def delete_in_db(id: str) -> bool:
|
100
|
+
if not id:
|
101
|
+
raise ValueError('Instance ID is required')
|
102
|
+
try:
|
103
|
+
result = supabase.table('instances').delete().eq('id', id).execute()
|
104
|
+
print('Deleted instance', result)
|
105
|
+
if not result.data:
|
106
|
+
raise ValueError('Instance ID not found')
|
107
|
+
else:
|
108
|
+
return True
|
109
|
+
except Exception as e:
|
110
|
+
print('Error deleting instance', str(e))
|
111
|
+
raise e
|
112
|
+
|
113
|
+
@staticmethod
|
114
|
+
def get_by_title_and_agent(title: str, agent_id: str) -> dict:
|
115
|
+
if not title:
|
116
|
+
raise ValueError('Instance title is required')
|
117
|
+
if not agent_id:
|
118
|
+
raise ValueError('Agent ID is required')
|
119
|
+
try:
|
120
|
+
print(f"Fetching instance with title {title} and agent ID {agent_id}")
|
121
|
+
result = supabase.table('instances').select('*').eq('title', title).eq('agent_id', agent_id).limit(1).execute()
|
122
|
+
if not result or not result.data:
|
123
|
+
print(f"No instance found with the given title {title} and agent ID {agent_id}: {result}")
|
124
|
+
return None
|
125
|
+
instance_dict = result.data[0]
|
126
|
+
instance_dict["agent_id"] = str(instance_dict["agent_id"])
|
127
|
+
instance_dict["id"] = str(instance_dict["id"])
|
128
|
+
print(f"Fetched instance: {instance_dict}")
|
129
|
+
return instance_dict
|
130
|
+
except Exception as e:
|
131
|
+
print('[Instance.get_by_title_and_agent] Error fetching instance', str(e))
|
132
|
+
raise e
|
133
|
+
|
134
|
+
@staticmethod
|
135
|
+
def get_in_db(id: str) -> InstanceModel:
|
136
|
+
if not id:
|
137
|
+
raise ValueError('Instance ID is required')
|
138
|
+
try:
|
139
|
+
result = supabase.table('instances').select('*').eq('id', id).limit(1).execute()
|
140
|
+
instance_dict = result.data[0]
|
141
|
+
instance_dict["agent_id"] = str(instance_dict["agent_id"])
|
142
|
+
instance_dict["id"] = str(instance_dict["id"])
|
143
|
+
print(f"Fetched instance: {instance_dict}")
|
144
|
+
instance = InstanceModel(**instance_dict)
|
145
|
+
return instance
|
146
|
+
except Exception as e:
|
147
|
+
print('[Instance.get_in_db] Error fetching instance', str(e))
|
148
|
+
raise e
|
149
|
+
|
150
|
+
@staticmethod
|
151
|
+
def get_all_in_db(limit: int = 10, created_at_lt: datetime = datetime.now()) -> [InstanceModel]:
|
152
|
+
try:
|
153
|
+
result = supabase.from_('instances') \
|
154
|
+
.select("*") \
|
155
|
+
.limit(limit) \
|
156
|
+
.lt('created_at', created_at_lt) \
|
157
|
+
.order('created_at', desc=True) \
|
158
|
+
.execute()
|
159
|
+
instance_models = [InstanceModel(**{k: str(v) if not isinstance(v, list) else v for k, v in instance.items()}) for instance in result.data]
|
160
|
+
return instance_models
|
161
|
+
except Exception as e:
|
162
|
+
print('[Instance.get_all_in_db] Error fetching instances', str(e))
|
163
|
+
raise e
|
@@ -0,0 +1,10 @@
|
|
1
|
+
fyodorov_llm_agents/agents/agent.py,sha256=vVBCEBpG11m4ae11Mr94rF5TJpuBluI_loQPDTw734w,5044
|
2
|
+
fyodorov_llm_agents/agents/openai.py,sha256=FA5RS7yn3JwvFA8PXju60XSYC_2oUZFNgBUzeIYtGv0,1154
|
3
|
+
fyodorov_llm_agents/instances/instance.py,sha256=edPOcn6qIB6Gnbr5d2_4HBaCk3sa8XYxfJPSHrcDLHE,8218
|
4
|
+
fyodorov_llm_agents/tools/mcp_tool_model.py,sha256=i7oFZReVGZsHN2K8T7mCAGF4t92wMMIR9mCkRHUgKsI,4413
|
5
|
+
fyodorov_llm_agents/tools/mcp_tool_service.py,sha256=9tDvSdKpEAOKKU5MHImUqTOc6MZyk1hEjs3GpzgQUsk,5542
|
6
|
+
fyodorov_llm_agents/tools/tool.py,sha256=HyOk0X_3XE23sa8J-8UZx657tJ0sxwZWMbA4OPxXU6E,7940
|
7
|
+
fyodorov_llm_agents-0.3.8.dist-info/METADATA,sha256=u-fvGhE1XF17eJcWQQNNbYSKq8sL1BV1yV9VFyMb878,550
|
8
|
+
fyodorov_llm_agents-0.3.8.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
9
|
+
fyodorov_llm_agents-0.3.8.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
|
10
|
+
fyodorov_llm_agents-0.3.8.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
fyodorov_llm_agents/agents/agent.py,sha256=EM4uq94_S3ZYH6aLT7iYu-FeIfc6VpkiuxXgQhp1lug,6560
|
2
|
-
fyodorov_llm_agents/agents/openai.py,sha256=FA5RS7yn3JwvFA8PXju60XSYC_2oUZFNgBUzeIYtGv0,1154
|
3
|
-
fyodorov_llm_agents/tools/mcp_tool_model.py,sha256=i7oFZReVGZsHN2K8T7mCAGF4t92wMMIR9mCkRHUgKsI,4413
|
4
|
-
fyodorov_llm_agents/tools/mcp_tool_service.py,sha256=9tDvSdKpEAOKKU5MHImUqTOc6MZyk1hEjs3GpzgQUsk,5542
|
5
|
-
fyodorov_llm_agents/tools/tool.py,sha256=HyOk0X_3XE23sa8J-8UZx657tJ0sxwZWMbA4OPxXU6E,7940
|
6
|
-
fyodorov_llm_agents-0.3.6.dist-info/METADATA,sha256=3dd7l6yvr2CzMVTwFvDrZFcgnBTZw8PlEiJt3gmfosg,550
|
7
|
-
fyodorov_llm_agents-0.3.6.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
8
|
-
fyodorov_llm_agents-0.3.6.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
|
9
|
-
fyodorov_llm_agents-0.3.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|