Skip to content

Commit 8e17af6

Browse files
authored
Merge pull request #143 from mindsdb/staging
Release 3.1.0
2 parents 31d1441 + 841290a commit 8e17af6

File tree

8 files changed

+102
-92
lines changed

8 files changed

+102
-92
lines changed

examples/using_agents_with_retrieval.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55
con = mindsdb_sdk.connect()
66

77
open_ai_key = os.getenv('OPENAI_API_KEY')
8-
model_name = 'gpt-4'
8+
model_name = 'gpt-4o'
99

1010
# Now create an agent that will use the model we just created.
1111
agent = con.agents.create(name=f'mindsdb_retrieval_agent_{model_name}_{uuid4().hex}',
12-
model='gpt-4',
12+
model=model_name,
1313
params={'return_context': True})
1414

1515
agent.add_file('./data/tokaido-rulebook.pdf', 'rule book for the board game Tokaido')
1616

17-
1817
question = "what are the rules for the game takaido?"
1918
answer = agent.completion([{'question': question, 'answer': None}])
2019
print(answer.context)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import mindsdb_sdk
2+
from uuid import uuid4
3+
import os
4+
5+
con = mindsdb_sdk.connect()
6+
7+
open_ai_key = os.getenv('OPENAI_API_KEY')
8+
model_name = 'gpt-4o'
9+
10+
# Now create an agent that will use the model we just created.
11+
agent = con.agents.create(name=f'mindsdb_retrieval_agent_{model_name}_{uuid4().hex}',
12+
model=model_name,
13+
params={'return_context': True})
14+
15+
agent.add_file('./data/tokaido-rulebook.pdf', 'rule book for the board game Tokaido')
16+
17+
question = "what are the rules for the game takaido?"
18+
19+
# Stream the completion
20+
completion_stream = agent.completion_stream([{'question': question, 'answer': None}])
21+
22+
# Process the streaming response
23+
full_response = ""
24+
for chunk in completion_stream:
25+
print(chunk) # Print the entire chunk for debugging
26+
if isinstance(chunk, dict):
27+
if 'output' in chunk:
28+
full_response += chunk['output']
29+
elif isinstance(chunk, str):
30+
full_response += chunk
31+
32+
print("\n\nFull response:")
33+
print(full_response)

mindsdb_sdk/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__title__ = 'mindsdb_sdk'
22
__package_name__ = 'mindsdb_sdk'
3-
__version__ = '3.0.2'
3+
__version__ = '3.1.0'
44
__description__ = "MindsDB Python SDK, provides an SDK to use a remote mindsdb instance"
55
__email__ = "[email protected]"
66
__author__ = 'MindsDB Inc'

mindsdb_sdk/agents.py

Lines changed: 42 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44
from uuid import uuid4
55
import datetime
66
import json
7-
import pandas as pd
87

9-
from mindsdb_sdk.databases import Databases
10-
from mindsdb_sdk.knowledge_bases import KnowledgeBase, KnowledgeBases
11-
from mindsdb_sdk.ml_engines import MLEngines
12-
from mindsdb_sdk.models import Model, Models
13-
from mindsdb_sdk.skills import Skill, Skills
8+
from mindsdb_sdk.knowledge_bases import KnowledgeBase
9+
from mindsdb_sdk.models import Model
10+
from mindsdb_sdk.skills import Skill
1411
from mindsdb_sdk.utils.objects_collection import CollectionBase
1512

1613
_DEFAULT_LLM_MODEL = 'gpt-4o'
14+
_DEFAULT_LLM_PROMPT = 'Answer the user"s question in a helpful way: {{question}}'
15+
1716

1817
class AgentCompletion:
1918
"""
@@ -25,6 +24,7 @@ class AgentCompletion:
2524
2625
2726
"""
27+
2828
def __init__(self, content: str, context: List[dict] = None):
2929
self.content = content
3030
self.context = context
@@ -76,6 +76,7 @@ class Agent:
7676
7777
>>> agents.drop('my_agent')
7878
"""
79+
7980
def __init__(
8081
self,
8182
name: str,
@@ -84,9 +85,9 @@ def __init__(
8485
params: dict,
8586
created_at: datetime.datetime,
8687
updated_at: datetime.datetime,
87-
provider: str= None,
88+
provider: str = None,
8889
collection: CollectionBase = None
89-
):
90+
):
9091
self.name = name
9192
self.model_name = model_name
9293
self.provider = provider
@@ -178,22 +179,25 @@ def from_json(cls, json: dict, collection: CollectionBase):
178179

179180
class Agents(CollectionBase):
180181
"""Collection for agents"""
181-
def __init__(self, api, project: str, knowledge_bases: KnowledgeBases, databases: Databases, models: Models, ml_engines: MLEngines, skills: Skills = None):
182+
183+
def __init__(self, project, api):
182184
self.api = api
183185
self.project = project
184-
self.skills = skills or Skills(self.api, project)
185-
self.databases = databases
186-
self.knowledge_bases = knowledge_bases
187-
self.ml_engines = ml_engines
188-
self.models = models
186+
187+
self.knowledge_bases = project.knowledge_bases
188+
self.models = project.models
189+
self.skills = project.skills
190+
191+
self.databases = project.server.databases
192+
self.ml_engines = project.server.ml_engines
189193

190194
def list(self) -> List[Agent]:
191195
"""
192196
List available agents.
193197
194198
:return: list of agents
195199
"""
196-
data = self.api.agents(self.project)
200+
data = self.api.agents(self.project.name)
197201
return [Agent.from_json(agent, self) for agent in data]
198202

199203
def get(self, name: str) -> Agent:
@@ -204,7 +208,7 @@ def get(self, name: str) -> Agent:
204208
205209
:return: agent with given name
206210
"""
207-
data = self.api.agent(self.project, name)
211+
data = self.api.agent(self.project.name, name)
208212
return Agent.from_json(data, self)
209213

210214
def completion(self, name: str, messages: List[dict]) -> AgentCompletion:
@@ -216,7 +220,7 @@ def completion(self, name: str, messages: List[dict]) -> AgentCompletion:
216220
217221
:return: completion from querying the agent
218222
"""
219-
data = self.api.agent_completion(self.project, name, messages)
223+
data = self.api.agent_completion(self.project.name, name, messages)
220224
if 'context' in data['message']:
221225
return AgentCompletion(data['message']['content'], data['message'].get('context'))
222226

@@ -231,7 +235,7 @@ def completion_stream(self, name, messages: List[dict]) -> Iterable[object]:
231235
232236
:return: iterable of completion chunks from querying the agent.
233237
"""
234-
return self.api.agent_completion_stream(self.project, name, messages)
238+
return self.api.agent_completion_stream(self.project.name, name, messages)
235239

236240
def _create_default_knowledge_base(self, agent: Agent, name: str) -> KnowledgeBase:
237241
# Make sure default ML engine for embeddings exists.
@@ -244,7 +248,7 @@ def _create_default_knowledge_base(self, agent: Agent, name: str) -> KnowledgeBa
244248
agent_model = self.models.get(agent.model_name)
245249
training_options = json.loads(agent_model.data.get('training_options', '{}'))
246250
training_options_using = training_options.get('using', {})
247-
api_key_params = {k:v for k, v in training_options_using.items() if 'api_key' in k}
251+
api_key_params = {k: v for k, v in training_options_using.items() if 'api_key' in k}
248252
kb = self.knowledge_bases.create(name, params=api_key_params)
249253
else:
250254
kb = self.knowledge_bases.create(name)
@@ -298,7 +302,6 @@ def add_files(self, name: str, file_paths: List[str], description: str, knowledg
298302
agent.skills.append(file_retrieval_skill)
299303
self.update(agent.name, agent)
300304

301-
302305
def add_file(self, name: str, file_path: str, description: str, knowledge_base: str = None):
303306
"""
304307
Add a file to the agent for retrieval.
@@ -395,50 +398,14 @@ def add_database(self, name: str, database: str, tables: List[str], description:
395398
agent.skills.append(database_sql_skill)
396399
self.update(agent.name, agent)
397400

398-
def _create_ml_engine_if_not_exists(self, name: str = 'langchain'):
399-
try:
400-
_ = self.ml_engines.get('langchain')
401-
except Exception:
402-
# Create the engine if it doesn't exist.
403-
_ = self.ml_engines.create('langchain', handler='langchain')
404-
405-
def _create_model_if_not_exists(self, name: str, model: Union[Model, dict, str]) -> str:
406-
# Create langchain engine if it doesn't exist.
407-
self._create_ml_engine_if_not_exists()
408-
# Create a default model if it doesn't exist.
409-
default_model_params = {
410-
'predict': 'answer',
411-
'engine': 'langchain',
412-
'prompt_template': 'Answer the user"s question in a helpful way: {{question}}',
413-
# Use GPT-4 by default.
414-
'provider': 'openai',
415-
'model_name': 'gpt-4'
416-
}
417-
418-
if isinstance(model, dict):
419-
default_model_params.update(model)
420-
# Create model with passed in params.
421-
return self.models.create(
422-
f'{name}_default_model',
423-
**default_model_params
424-
).name
425-
426-
if model is None:
427-
# Create model with default params.
428-
return _DEFAULT_LLM_MODEL
429-
430-
if isinstance(model, Model):
431-
return model.name
432-
433-
return model
434-
435401
def create(
436402
self,
437403
name: str,
438404
model: Union[Model, dict, str] = None,
439405
provider: str = None,
440406
skills: List[Union[Skill, str]] = None,
441-
params: dict = None) -> Agent:
407+
params: dict = None,
408+
**kwargs) -> Agent:
442409
"""
443410
Create new agent and return it
444411
@@ -454,16 +421,28 @@ def create(
454421
for skill in skills:
455422
if isinstance(skill, str):
456423
# Check if skill exists.
424+
# TODO what this line does?
457425
_ = self.skills.get(skill)
458426
skill_names.append(skill)
459427
continue
460428
# Create the skill if it doesn't exist.
461429
_ = self.skills.create(skill.name, skill.type, skill.params)
462430
skill_names.append(skill.name)
463431

464-
model = self._create_model_if_not_exists(name, model)
432+
if params is None:
433+
params = {}
434+
params.update(kwargs)
435+
436+
if 'prompt_template' not in params:
437+
params['prompt_template'] = _DEFAULT_LLM_PROMPT
438+
439+
if model is None:
440+
model = _DEFAULT_LLM_MODEL
441+
elif isinstance(model, Model):
442+
model = model.name
443+
provider = 'mindsdb'
465444

466-
data = self.api.create_agent(self.project, name, model, provider, skill_names, params)
445+
data = self.api.create_agent(self.project.name, name, model, provider, skill_names, params)
467446
return Agent.from_json(data, self)
468447

469448
def update(self, name: str, updated_agent: Agent):
@@ -492,12 +471,12 @@ def update(self, name: str, updated_agent: Agent):
492471
_ = self.skills.create(skill.name, skill.type, skill.params)
493472
updated_skills.add(skill.name)
494473

495-
existing_agent = self.api.agent(self.project, name)
474+
existing_agent = self.api.agent(self.project.name, name)
496475
existing_skills = set([s['name'] for s in existing_agent['skills']])
497476
skills_to_add = updated_skills.difference(existing_skills)
498477
skills_to_remove = existing_skills.difference(updated_skills)
499478
data = self.api.update_agent(
500-
self.project,
479+
self.project.name,
501480
name,
502481
updated_agent.name,
503482
updated_agent.model_name,
@@ -513,4 +492,4 @@ def drop(self, name: str):
513492
514493
:param name: Name of the agent to be dropped
515494
"""
516-
_ = self.api.delete_agent(self.project, name)
495+
_ = self.api.delete_agent(self.project.name, name)

mindsdb_sdk/projects.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ class Project:
4848
4949
"""
5050

51-
def __init__(self, api, name, agents: Agents = None, skills: Skills = None, knowledge_bases: KnowledgeBases = None, databases: Databases = None, ml_engines: MLEngines = None):
51+
def __init__(self, server, api, name):
5252
self.name = name
5353
self.api = api
54+
self.server = server
5455

5556
self.models = Models(self, api)
5657

@@ -76,11 +77,10 @@ def __init__(self, api, name, agents: Agents = None, skills: Skills = None, know
7677
self.create_job = self.jobs.create
7778
self.drop_job = self.jobs.drop
7879

79-
self.databases = databases or Databases(api)
80-
self.knowledge_bases = knowledge_bases or KnowledgeBases(self, api)
80+
self.knowledge_bases = KnowledgeBases(self, api)
8181

82-
self.skills = skills or Skills(api, name)
83-
self.agents = agents or Agents(api, name, self.knowledge_bases, self.databases, self.models, ml_engines, self.skills)
82+
self.skills = Skills(self, api)
83+
self.agents = Agents(self, api)
8484

8585
def __repr__(self):
8686
return f'{self.__class__.__name__}({self.name})'
@@ -106,7 +106,6 @@ def drop_model_version(self, name: str, version: int):
106106
self.query(ast_query.to_string()).fetch()
107107

108108

109-
110109
class Projects(CollectionBase):
111110
"""
112111
Projects
@@ -133,8 +132,9 @@ class Projects(CollectionBase):
133132
134133
"""
135134

136-
def __init__(self, api):
135+
def __init__(self, server, api):
137136
self.api = api
137+
self.server = server
138138

139139
def _list_projects(self):
140140
data = self.api.sql_query("select NAME from information_schema.databases where TYPE='project'")
@@ -147,7 +147,7 @@ def list(self) -> List[Project]:
147147
:return: list of Project objects
148148
"""
149149
# select * from information_schema.databases where TYPE='project'
150-
return [Project(self.api, name) for name in self._list_projects()]
150+
return [Project(self.server, self.api, name) for name in self._list_projects()]
151151

152152
def get(self, name: str = 'mindsdb') -> Project:
153153
"""
@@ -158,7 +158,7 @@ def get(self, name: str = 'mindsdb') -> Project:
158158
"""
159159
if name not in self._list_projects():
160160
raise AttributeError("Project doesn't exist")
161-
return Project(self.api, name)
161+
return Project(self.server, self.api, name)
162162

163163
def create(self, name: str) -> Project:
164164
"""
@@ -175,7 +175,7 @@ def create(self, name: str) -> Project:
175175
)
176176

177177
self.api.sql_query(ast_query.to_string())
178-
return Project(self.api, name)
178+
return Project(self.server, self.api, name)
179179

180180
def drop(self, name: str):
181181
"""

mindsdb_sdk/server.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,24 @@ class Server(Project):
2727

2828
def __init__(self, api, skills: Skills = None, agents: Agents = None):
2929
# server is also mindsdb project
30-
project_name = 'mindsdb'
3130
self.databases = Databases(api)
3231
self.ml_engines = MLEngines(api)
33-
super().__init__(api, project_name, skills=skills, agents=agents, databases=self.databases, ml_engines=self.ml_engines)
32+
super().__init__(self, api, 'mindsdb')
3433

35-
self.projects = Projects(api)
34+
self.projects = Projects(self, api)
3635

3736
# old api
3837
self.get_project = self.projects.get
3938
self.list_projects = self.projects.list
4039
self.create_project = self.projects.create
4140
self.drop_project = self.projects.drop
4241

43-
4442
# old api
4543
self.get_database = self.databases.get
4644
self.list_databases = self.databases.list
4745
self.create_database = self.databases.create
4846
self.drop_database = self.databases.drop
4947

50-
5148
self.ml_handlers = Handlers(self.api, 'ml')
5249
self.data_handlers = Handlers(self.api, 'data')
5350

0 commit comments

Comments
 (0)