fyodorov-llm-agents 0.3.7__py3-none-any.whl → 0.3.9__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.
@@ -0,0 +1,40 @@
1
+ from pydantic import BaseModel, HttpUrl, Field
2
+ import re
3
+
4
+ MAX_TITLE_LENGTH = 80
5
+ VALID_CHARACTERS_REGEX = r'^[a-zA-Z0-9\s.,!?:;\'"-]+$'
6
+
7
+ class InstanceModel(BaseModel):
8
+ id: str = Field(None, alias='id')
9
+ agent_id: str # Links to AgentModel.id
10
+ title: str = ""
11
+ chat_history: list[dict] = []
12
+
13
+ def validate(self) -> bool:
14
+ try:
15
+ InstanceModel.validate_title(self.title)
16
+ except ValueError as e:
17
+ print("Instance model validation error:", e)
18
+ return False
19
+ else:
20
+ return True
21
+
22
+ def to_dict(self) -> dict:
23
+ data = {
24
+ 'agent_id': str(self.agent_id),
25
+ 'title': self.title,
26
+ 'chat_history': self.chat_history,
27
+ }
28
+ if self.id is not None:
29
+ data['id'] = str(self.id)
30
+ return data
31
+
32
+ @staticmethod
33
+ def validate_title(title: str) -> str:
34
+ if not title:
35
+ raise ValueError('Title is required')
36
+ if len(title) > MAX_TITLE_LENGTH:
37
+ raise ValueError('Title exceeds maximum length')
38
+ if not re.match(VALID_CHARACTERS_REGEX, title):
39
+ raise ValueError('Title contains invalid characters')
40
+ return title
@@ -0,0 +1,162 @@
1
+ from datetime import datetime
2
+ from supabase import Client
3
+ from fyodorov_utils.config.supabase import get_supabase
4
+ from .agent import Agent
5
+ from .providers.provider_service import Provider
6
+
7
+ from fyodorov_llm_agents.agents.agent import Agent as AgentModel
8
+ from fyodorov_llm_agents.models.llm_model import LLMModel
9
+ from fyodorov_llm_agents.models.llm_service import LLM
10
+ from fyodorov_llm_agents.instances.instance_model import InstanceModel
11
+
12
+ supabase: Client = get_supabase()
13
+
14
+ JWT = "eyJhbGciOiJIUzI1NiIsImtpZCI6Im14MmVrTllBY3ZYN292LzMiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzA3MzI0MTMxLCJpYXQiOjE3MDczMjA1MzEsImlzcyI6Imh0dHBzOi8vbGptd2R2ZWZrZ3l4cnVjc2dla3cuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6IjljYzYzOWQ0LWUwMzItNDM3Zi1hNWVhLTUzNDljZGE0YTNmZCIsImVtYWlsIjoiZGFuaWVsQGRhbmllbHJhbnNvbS5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7Imludml0ZV9jb2RlIjoiUkFOU09NIn0sInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiYWFsIjoiYWFsMSIsImFtciI6W3sibWV0aG9kIjoicGFzc3dvcmQiLCJ0aW1lc3RhbXAiOjE3MDczMjA1MzF9XSwic2Vzc2lvbl9pZCI6ImE4MTM4NmE1LTUxZTUtNDkyMS04ZjM3LWMyYWE3ODlhZDRhZiJ9.NNZA2rm1IQQ9wAhpyC8taMqregRmy8I9oZgT0P5heBg"
15
+
16
+ class Instance(InstanceModel):
17
+
18
+ async def chat_w_fn_calls(self, input: str = "", access_token: str = JWT, user_id: str = "") -> str:
19
+ agent: AgentModel = await Agent.get_in_db(access_token=access_token, id = self.agent_id)
20
+ model: LLMModel = await LLM.get_model(access_token, user_id, id = agent.modelid)
21
+ print(f"Model fetched via LLM.get_model in chat_w_fn_calls: {model}")
22
+ provider: Provider = await Provider.get_provider_by_id(access_token, id = model.provider)
23
+ prompt = f"{agent.prompt}\n\n{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
24
+ agent.prompt = prompt
25
+ agent.model = model.base_model
26
+ agent.api_key = provider.api_key
27
+ agent.api_url = provider.api_url
28
+ # for index, tool in enumerate(agent.tools):
29
+ # if isinstance(tool, str):
30
+ # agent.tools[index] = Tool.get_by_name_and_user_id(access_token, tool, user_id)
31
+ # print(f"Tool fetched via Tool.get_by_name_and_user_id in chat_w_fn_calls: {agent.tools[index]}")
32
+ res = agent.call_with_fn_calling(input=input, history=self.chat_history)
33
+ self.chat_history.append({
34
+ "role": "user",
35
+ "content": input
36
+ })
37
+ self.chat_history.append({
38
+ "role": "assistant",
39
+ "content": res["answer"]
40
+ })
41
+ # Update history
42
+ await self.create_in_db(instance=self)
43
+ return res
44
+
45
+ @staticmethod
46
+ async def create_in_db(instance: InstanceModel) -> dict:
47
+ try:
48
+ existing_instance = Instance.get_by_title_and_agent(instance.title, instance.agent_id)
49
+ if existing_instance:
50
+ needs_update = False
51
+ for key, value in instance.to_dict().items():
52
+ if value != existing_instance[key]:
53
+ print(f"Instance {key} needs updating: {value} != {existing_instance[key]}")
54
+ needs_update = True
55
+ existing_instance[key] = value
56
+ if needs_update:
57
+ print('Instance already exists, will update:', existing_instance)
58
+ instance_dict = await Instance.update_in_db(existing_instance["id"], existing_instance)
59
+ else:
60
+ print('Instance already exists and no update needed:', existing_instance)
61
+ instance_dict = existing_instance
62
+ else:
63
+ print("Creating instance in DB:", instance.to_dict())
64
+ result = supabase.table('instances').upsert(instance.to_dict()).execute()
65
+ if not result or not result.data:
66
+ print(f"Error creating instance in DB: {result}")
67
+ raise ValueError('Error creating instance in DB')
68
+ print(f"Result of creating instance in DB: {result}")
69
+ instance_dict = result.data[0]
70
+ instance_dict["id"] = str(instance_dict["id"])
71
+ instance_dict["agent_id"] = str(instance_dict["agent_id"])
72
+ return instance_dict
73
+ except Exception as e:
74
+ print(f"An error occurred while creating instance: {e}")
75
+ if 'code' in e and e.code == '23505':
76
+ print('Instance already exists')
77
+ instance_dict = Instance.get_by_title_and_agent(instance.title, instance.agent_id)
78
+ return instance_dict
79
+ print('Error creating instance', str(e))
80
+ raise e
81
+
82
+ @staticmethod
83
+ async def update_in_db(id: str, instance: dict) -> InstanceModel:
84
+ if not id:
85
+ raise ValueError('Instance ID is required')
86
+ try:
87
+ print(f"Updating instance in DB with ID: {id}, data: {instance}")
88
+ result = supabase.table('instances').update(instance).eq('id', id).execute()
89
+ print(f"Result of update: {result}")
90
+ instance_dict = result.data[0]
91
+ instance_dict["id"] = str(instance_dict["id"])
92
+ return instance_dict
93
+ except Exception as e:
94
+ print('An error occurred while updating instance:', id, str(e))
95
+ raise
96
+
97
+ @staticmethod
98
+ async def delete_in_db(id: str) -> bool:
99
+ if not id:
100
+ raise ValueError('Instance ID is required')
101
+ try:
102
+ result = supabase.table('instances').delete().eq('id', id).execute()
103
+ print('Deleted instance', result)
104
+ if not result.data:
105
+ raise ValueError('Instance ID not found')
106
+ else:
107
+ return True
108
+ except Exception as e:
109
+ print('Error deleting instance', str(e))
110
+ raise e
111
+
112
+ @staticmethod
113
+ def get_by_title_and_agent(title: str, agent_id: str) -> dict:
114
+ if not title:
115
+ raise ValueError('Instance title is required')
116
+ if not agent_id:
117
+ raise ValueError('Agent ID is required')
118
+ try:
119
+ print(f"Fetching instance with title {title} and agent ID {agent_id}")
120
+ result = supabase.table('instances').select('*').eq('title', title).eq('agent_id', agent_id).limit(1).execute()
121
+ if not result or not result.data:
122
+ print(f"No instance found with the given title {title} and agent ID {agent_id}: {result}")
123
+ return None
124
+ instance_dict = result.data[0]
125
+ instance_dict["agent_id"] = str(instance_dict["agent_id"])
126
+ instance_dict["id"] = str(instance_dict["id"])
127
+ print(f"Fetched instance: {instance_dict}")
128
+ return instance_dict
129
+ except Exception as e:
130
+ print('[Instance.get_by_title_and_agent] Error fetching instance', str(e))
131
+ raise e
132
+
133
+ @staticmethod
134
+ def get_in_db(id: str) -> InstanceModel:
135
+ if not id:
136
+ raise ValueError('Instance ID is required')
137
+ try:
138
+ result = supabase.table('instances').select('*').eq('id', id).limit(1).execute()
139
+ instance_dict = result.data[0]
140
+ instance_dict["agent_id"] = str(instance_dict["agent_id"])
141
+ instance_dict["id"] = str(instance_dict["id"])
142
+ print(f"Fetched instance: {instance_dict}")
143
+ instance = InstanceModel(**instance_dict)
144
+ return instance
145
+ except Exception as e:
146
+ print('[Instance.get_in_db] Error fetching instance', str(e))
147
+ raise e
148
+
149
+ @staticmethod
150
+ def get_all_in_db(limit: int = 10, created_at_lt: datetime = datetime.now()) -> [InstanceModel]:
151
+ try:
152
+ result = supabase.from_('instances') \
153
+ .select("*") \
154
+ .limit(limit) \
155
+ .lt('created_at', created_at_lt) \
156
+ .order('created_at', desc=True) \
157
+ .execute()
158
+ instance_models = [InstanceModel(**{k: str(v) if not isinstance(v, list) else v for k, v in instance.items()}) for instance in result.data]
159
+ return instance_models
160
+ except Exception as e:
161
+ print('[Instance.get_all_in_db] Error fetching instances', str(e))
162
+ raise e
@@ -0,0 +1,46 @@
1
+ from pydantic import BaseModel, HttpUrl
2
+ from typing import Literal
3
+
4
+ class LLMModel(BaseModel):
5
+ id: str | None = None
6
+ name: str
7
+ provider: str
8
+ params: dict | None = None
9
+ mode: str = 'chat'
10
+ base_model: str
11
+ input_cost_per_token: float | None = None
12
+ output_cost_per_token: float | None = None
13
+ max_tokens: int | None = None
14
+
15
+ def to_dict(self):
16
+ return {
17
+ 'name': self.name,
18
+ 'provider': self.provider,
19
+ 'params': self.params,
20
+ 'mode': self.mode,
21
+ 'base_model': self.base_model,
22
+ 'input_cost_per_token': self.input_cost_per_token,
23
+ 'output_cost_per_token': self.output_cost_per_token,
24
+ 'max_tokens': self.max_tokens
25
+ }
26
+
27
+ @staticmethod
28
+ def from_dict(data) -> 'LLMModel':
29
+ input_dict = {
30
+ "name": data['name'],
31
+ "provider": data['provider'],
32
+ }
33
+ if 'model_info' in data and 'base_model' in data['model_info']:
34
+ input_dict['base_model'] = data['model_info']['base_model']
35
+ if 'params' in data:
36
+ input_dict['params'] = data['params']
37
+ if 'mode' in data:
38
+ input_dict['mode'] = data['mode']
39
+ if 'input_cost_per_token' in data:
40
+ input_dict['input_cost_per_token'] = data['input_cost_per_token']
41
+ if 'output_cost_per_token' in data:
42
+ input_dict['output_cost_per_token'] = data['output_cost_per_token']
43
+ if 'max_tokens' in data:
44
+ input_dict['max_tokens'] = data['max_tokens']
45
+ print('Input dict for LLMModel:', input_dict)
46
+ return LLMModel(**input_dict)
@@ -0,0 +1,97 @@
1
+
2
+ from pydantic import BaseModel
3
+ import re
4
+ from datetime import datetime
5
+ from models.model import LLMModel
6
+ from .provider import Provider
7
+ from supabase import Client
8
+ from fyodorov_utils.config.supabase import get_supabase
9
+
10
+ supabase: Client = get_supabase()
11
+
12
+ class LLM(LLMModel):
13
+
14
+ @staticmethod
15
+ async def update_model_in_db(access_token: str, user_id: str, name: str, update: dict) -> dict:
16
+ if not user_id or not name:
17
+ raise ValueError('Model name and User ID is required')
18
+ try:
19
+ result = supabase.table('models').update(update).eq('user_id', user_id).eq('name', name).execute()
20
+ update = result.data[0]
21
+ print('Updated model:', update)
22
+ return update
23
+ except Exception as e:
24
+ print(f"Error updating model with user_id {user_id} and name {name} "
25
+ f"and update {update} ")
26
+ raise e
27
+
28
+ @staticmethod
29
+ async def save_model_in_db(access_token: str, user_id: str, model: LLMModel) -> dict:
30
+ try:
31
+ supabase = get_supabase(access_token)
32
+ provider = await Provider.get_or_create_provider(access_token, user_id, model.provider)
33
+ model_dict = model.to_dict()
34
+ model_dict['provider'] = provider.id
35
+ model_dict['user_id'] = user_id
36
+ result = supabase.table('models').upsert(model_dict).execute()
37
+ model_dict = result.data[0]
38
+ return model_dict
39
+ except Exception as e:
40
+ print('Error saving model', str(e))
41
+ raise e
42
+
43
+ @staticmethod
44
+ async def delete_model_in_db(access_token: str, user_id: str, name: str, id: str) -> bool:
45
+ try:
46
+ supabase = get_supabase(access_token)
47
+ if id:
48
+ result = supabase.table('models').delete().eq('id', id).execute()
49
+ elif user_id and name:
50
+ result = supabase.table('models').delete().eq('user_id', user_id).eq('name', name).execute()
51
+ else:
52
+ raise ValueError('Some form of id is required to delete a model')
53
+ print('Deleted model', result.data)
54
+ return True
55
+ except Exception as e:
56
+ print('Error deleting model', str(e))
57
+ raise e
58
+
59
+ @staticmethod
60
+ async def get_model(access_token: str, user_id: str = None, name: str = None, id: str = None) -> LLMModel:
61
+ try:
62
+ supabase = get_supabase(access_token)
63
+ if id:
64
+ print(f"Getting model with id: {id}")
65
+ result = supabase.table('models').select('*').eq('id', id).execute()
66
+ elif user_id and name:
67
+ print(f"Getting model with name: {name} and user_id: {user_id}")
68
+ result = supabase.table('models').select('*').eq('user_id', user_id).eq('name', name).execute()
69
+ else:
70
+ raise ValueError('Some form of id is required to retrieve a model')
71
+ print('Fetched model', result)
72
+ if not result or not result.data:
73
+ return None
74
+ model_dict = result.data[0]
75
+ model_dict['id'] = str(model_dict['id'])
76
+ model_dict['provider'] = str(model_dict['provider'])
77
+ model = LLMModel(**model_dict)
78
+ return model
79
+ except Exception as e:
80
+ print('Error fetching model from db', str(e))
81
+ raise e
82
+
83
+ @staticmethod
84
+ async def get_models(limit: int = 10, created_at_lt: datetime = datetime.now()) -> [dict]:
85
+ try:
86
+ result = supabase.table('models') \
87
+ .select('*') \
88
+ .order('created_at', desc=True) \
89
+ .limit(limit) \
90
+ .lt('created_at', created_at_lt) \
91
+ .execute()
92
+ data = result.data
93
+ print('Fetched models', data)
94
+ return data
95
+ except Exception as e:
96
+ print('Error fetching models', str(e))
97
+ raise e
@@ -0,0 +1,32 @@
1
+ from pydantic import BaseModel, HttpUrl
2
+ from typing import Literal
3
+
4
+ Provider = Literal['openai', 'mistral', 'ollama', 'openrouter']
5
+
6
+ class ProviderModel(BaseModel):
7
+ id: str | None = None
8
+ name: Provider
9
+ api_key: str | None = None
10
+ api_url: HttpUrl | None = None
11
+
12
+ def to_dict(self):
13
+ dict = {
14
+ 'name': self.name.lower(),
15
+ }
16
+ if self.api_url is not None:
17
+ dict['api_url'] = str(self.api_url)
18
+ if self.api_key is not None:
19
+ dict['api_key'] = self.api_key
20
+ if self.id is not None:
21
+ dict['id'] = self.id
22
+ return dict
23
+
24
+ def from_dict(data):
25
+ name = data['name'] if 'name' in data else None
26
+ api_url = data['api_url'] if 'api_url' in data else None
27
+ api_key = data['api_key'] if 'api_key' in data else None
28
+ return ProviderModel(
29
+ name=name.lower(),
30
+ api_key=api_key,
31
+ api_url=api_url,
32
+ )
@@ -0,0 +1,138 @@
1
+ from datetime import datetime
2
+ from .provider_model import ProviderModel
3
+ from supabase import Client
4
+ from fyodorov_utils.config.supabase import get_supabase
5
+
6
+ supabase: Client = get_supabase()
7
+
8
+
9
+ class Provider(ProviderModel):
10
+
11
+ @staticmethod
12
+ async def update_provider_in_db(id: str, update: dict) -> dict:
13
+ if not id:
14
+ raise ValueError('Provider ID is required')
15
+ try:
16
+ result = supabase.table('providers').update(update).eq('id', id).execute()
17
+ update = result.data[0]
18
+ print('Updated provider:', update)
19
+ return update
20
+ except Exception as e:
21
+ print(f"Error updating provider with id {id} "
22
+ f"and update {update} ")
23
+ raise e
24
+
25
+ @staticmethod
26
+ async def save_provider_in_db(access_token: str, provider: ProviderModel, user_id: str) -> dict:
27
+ try:
28
+ print('Access token for saving provider:', access_token)
29
+ supabase = get_supabase(access_token)
30
+ provider.name = provider.name.lower()
31
+ if not provider.api_url or provider.api_url == "":
32
+ if provider.name == "openai":
33
+ provider.api_url = "https://api.openai.com/v1"
34
+ elif provider.name == "mistral":
35
+ provider.api_url = "https://api.mistral.ai/v1"
36
+ elif provider.name == "ollama":
37
+ provider.api_url = "http://localhost:11434/v1"
38
+ elif provider.name == "openrouter":
39
+ provider.api_url = "https://openrouter.ai/api/v1"
40
+ else:
41
+ raise ValueError('No URL provided when creating a provider')
42
+ print('Setting provider api_url to', provider.api_url)
43
+ provider_dict = provider.to_dict()
44
+ provider_dict['user_id'] = user_id
45
+ print('Provider dict before merging existing row:', provider_dict)
46
+ # Check if the provider already exists based on name and user_id
47
+ existing_provider = await Provider.get_provider(access_token, user_id, provider.name)
48
+ if existing_provider:
49
+ tmp = {**existing_provider.to_dict(), **provider_dict}
50
+ provider_dict = tmp
51
+ print('Saving provider', provider_dict)
52
+ result = supabase.table('providers').upsert(provider_dict).execute()
53
+ provider = result.data[0]
54
+ print('Saved provider', provider)
55
+ return provider
56
+ except Exception as e:
57
+ print('Error saving provider', str(e))
58
+ if e.code == '23505':
59
+ print('Provider already exists')
60
+ return provider
61
+ raise e
62
+
63
+ @staticmethod
64
+ async def delete_provider_in_db(id) -> bool:
65
+ if not id:
66
+ raise ValueError('Provider ID is required')
67
+ try:
68
+ result = supabase.table('providers').delete().eq('id', id).execute()
69
+ return True
70
+ except Exception as e:
71
+ print('Error deleting provider', str(e))
72
+ raise e
73
+
74
+ @staticmethod
75
+ async def get_provider_by_id(access_token: str, id: str) -> ProviderModel:
76
+ if not id:
77
+ raise ValueError('Provider ID is required')
78
+ try:
79
+ supabase = get_supabase(access_token)
80
+ result = supabase.table('providers').select('*').eq('id', id).limit(1).execute()
81
+ provider_dict = result.data[0]
82
+ print('Fetched provider', provider_dict)
83
+ provider_dict['id'] = str(provider_dict['id'])
84
+ provider = ProviderModel(**provider_dict)
85
+ return provider
86
+ except Exception as e:
87
+ print('Error fetching provider', str(e))
88
+ raise e
89
+
90
+ @staticmethod
91
+ async def get_provider(access_token: str, user_id: str, name: str) -> ProviderModel:
92
+ print(f"Getting provider with name: {name} and user_id: {user_id}")
93
+ if not name:
94
+ raise ValueError('Provider name is required')
95
+ if not user_id:
96
+ raise ValueError('User ID is required')
97
+ try:
98
+ supabase = get_supabase(access_token)
99
+ print('Got access token for getting provider:', access_token)
100
+ result = supabase.table('providers').select('*')\
101
+ .eq('user_id', user_id)\
102
+ .eq('name', name.lower())\
103
+ .limit(1).execute()
104
+ print('Result of getting provider:', result)
105
+ provider_dict = result.data[0]
106
+ print('Fetched provider', provider_dict)
107
+ provider_dict['id'] = str(provider_dict['id'])
108
+ provider = ProviderModel(**provider_dict)
109
+ return provider
110
+ except Exception as e:
111
+ print('Error fetching provider', str(e))
112
+ raise e
113
+
114
+ @staticmethod
115
+ async def get_or_create_provider(access_token: str, user_id: str, name: str) -> ProviderModel:
116
+ try:
117
+ provider = await Provider.get_provider(access_token, user_id, name)
118
+ return provider
119
+ except Exception as e:
120
+ provider = ProviderModel(name=name.lower())
121
+ provider = await Provider.save_provider_in_db(access_token, provider, user_id)
122
+ return provider
123
+
124
+ @staticmethod
125
+ async def get_providers(limit: int = 10, created_at_lt: datetime = datetime.now()) -> [dict]:
126
+ try:
127
+ result = supabase.table('providers') \
128
+ .select('*') \
129
+ .order('created_at', desc=True) \
130
+ .limit(limit) \
131
+ .lt('created_at', created_at_lt) \
132
+ .execute()
133
+ data = result.data
134
+ print('Fetched providers', data)
135
+ return data
136
+ except Exception as e:
137
+ print('Error fetching providers', str(e))
138
+ raise e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fyodorov_llm_agents
3
- Version: 0.3.7
3
+ Version: 0.3.9
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
@@ -0,0 +1,15 @@
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_model.py,sha256=PQaoVSH9H4qp_wcLvyT_QgvNtwf9oehOxZaGI6mv1bA,1206
4
+ fyodorov_llm_agents/instances/instance_service.py,sha256=5HCgnaE9cd2HR1HqZFADKozVHR5SRvGHvXTRSB5Qiq4,8250
5
+ fyodorov_llm_agents/models/llm_model.py,sha256=aQtXtB7kRpnVdbPu-nmTGAaflbtKz3DPkgcckf1srsg,1645
6
+ fyodorov_llm_agents/models/llm_service.py,sha256=613PLLGiDzkCfkVbt0XDlRwTQRL06QPyr9bfsbwQtPk,3989
7
+ fyodorov_llm_agents/providers/provider_model.py,sha256=OyCK6WMRhyElsp88gILg0wso-OPHI7f55gEeypsJ7O0,957
8
+ fyodorov_llm_agents/providers/provider_service.py,sha256=GST-NLV8aLPsvapQEvgT_qHGYu7IpS5Xsut60XFmD-g,5865
9
+ fyodorov_llm_agents/tools/mcp_tool_model.py,sha256=i7oFZReVGZsHN2K8T7mCAGF4t92wMMIR9mCkRHUgKsI,4413
10
+ fyodorov_llm_agents/tools/mcp_tool_service.py,sha256=9tDvSdKpEAOKKU5MHImUqTOc6MZyk1hEjs3GpzgQUsk,5542
11
+ fyodorov_llm_agents/tools/tool.py,sha256=HyOk0X_3XE23sa8J-8UZx657tJ0sxwZWMbA4OPxXU6E,7940
12
+ fyodorov_llm_agents-0.3.9.dist-info/METADATA,sha256=5dPcGRcYhgr6oKGL1AopHd2kPYLooD5oGM8O7HD2jps,550
13
+ fyodorov_llm_agents-0.3.9.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
14
+ fyodorov_llm_agents-0.3.9.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
15
+ fyodorov_llm_agents-0.3.9.dist-info/RECORD,,
@@ -1,9 +0,0 @@
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/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.7.dist-info/METADATA,sha256=gaov2jthap8Qu8luUtqUOwKrKq0PlwdZhvHO25bQRMA,550
7
- fyodorov_llm_agents-0.3.7.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
8
- fyodorov_llm_agents-0.3.7.dist-info/top_level.txt,sha256=4QOslsBp8Gh7ng25DceA7fHp4KguTIdAxwURz97gH-g,20
9
- fyodorov_llm_agents-0.3.7.dist-info/RECORD,,