1- from typing import List , Union , Iterable
1+ from openai import OpenAI
2+ from typing import Dict , List , Optional , Union , Iterable
3+
24import minds .utils as utils
35import minds .exceptions as exc
4- from minds .datasources import Datasource , DatabaseConfig , DatabaseTables , DatabaseConfigBase
5- from minds .knowledge_bases import KnowledgeBase , KnowledgeBaseConfig
6+ # from minds.knowledge_bases import KnowledgeBase, KnowledgeBaseConfig
67
78
89class Mind :
@@ -44,132 +45,38 @@ def __repr__(self):
4445 f'datasources={ self .datasources } , '
4546 f'status={ self .status } )' )
4647
47- def update (
48- self ,
49- name : str = None ,
50- model_name : str = None ,
51- provider = None ,
52- datasources = None ,
53- # knowledge_bases=None,
54- parameters = None ,
55- ):
56- """
57- Update mind
58-
59- If parameter is set it will be applied to mind
60-
61- Datasource can be passed as
62- - name, str
63- - Datasource object (minds.datasources.Database)
64- - datasource config (minds.datasources.DatabaseConfig), in this case datasource will be created
65-
66- Knowledge base can be passed as
67- - name, str
68- - KnowledgeBase object (minds.knowledge_bases.KnowledgeBase)
69- - Knowledge base config (minds.knowledge_bases.KnowledgeBaseConfig), in this case knowledge base will be created
70-
71- :param name: new name of the mind, optional
72- :param model_name: new llm model name, optional
73- :param provider: new llm provider, optional
74- :param datasources: alter list of datasources used by mind, optional
75- :param knowledge_bases: alter list of knowledge bases used by mind, optional
76- :param parameters, dict: alter other parameters of the mind, optional
77- """
78- data = {}
79-
80- if name is not None :
81- utils .validate_mind_name (name )
82-
83- if datasources is not None :
84- ds_list = []
85- for ds in datasources :
86- ds_list .append (self .client .minds ._check_datasource (ds ))
87- data ['datasources' ] = ds_list
88-
89- # if knowledge_bases is not None:
90- # kb_names = []
91- # for kb in knowledge_bases:
92- # kb = self.client.minds._check_knowledge_base(kb)
93- # kb_names.append(kb)
94- # data['knowledge_bases'] = kb_names
95-
96- if name is not None :
97- data ['name' ] = name
98- if model_name is not None :
99- data ['model_name' ] = model_name
100- if provider is not None :
101- data ['provider' ] = provider
102- if parameters is not None :
103- data ['parameters' ] = parameters
104-
105- self .api .put (
106- f'/minds/{ self .name } ' ,
107- data = data
108- )
109-
110- if name is not None and name != self .name :
111- self .name = name
112-
113- refreshed_mind = self .client .minds .get (self .name )
114- self .model_name = refreshed_mind .model_name
115- self .provider = refreshed_mind .provider
116- self .parameters = refreshed_mind .parameters
117- self .created_at = refreshed_mind .created_at
118- self .updated_at = refreshed_mind .updated_at
119- self .datasources = refreshed_mind .datasources
120- # self.knowledge_bases = refreshed_mind.knowledge_bases
121-
122- def add_datasource (self , datasource : Datasource ):
48+ def add_datasource (self , datasource_name : str , tables : Optional [List [str ]] = None ) -> None :
12349 """
124- Add datasource to mind
125- Datasource can be passed as
126- - name, str
127- - Datasource object (minds.datasources.Database)
128- - datasource config (minds.datasources.DatabaseConfig), in this case datasource will be created
50+ Add an existing Datasource to a Mind.
12951
130- :param datasource: input datasource
52+ :param datasource_name: name of the datasource to add.
53+ :param tables: list of tables to use from the datasource, optional.
13154 """
132- ds_name = self .client .minds ._check_datasource (datasource )['name' ]
133- existing_datasources = self .datasources or []
134-
135- self .api .put (
55+ response = self .api .put (
13656 f'/minds/{ self .name } ' ,
13757 data = {
138- 'datasources' : existing_datasources + [{'name' : ds_name }]
58+ 'datasources' : self . datasources + [{'name' : datasource_name , 'tables' : tables }]
13959 }
14060 )
141- updated = self .client .minds .get (self .name )
61+ updated_mind = response .json ()
62+ self .datasources = updated_mind ['datasources' ]
63+ self .status = updated_mind ['status' ]
14264
143- self .datasources = updated .datasources
144-
145- def del_datasource (self , datasource : Union [Datasource , str ]):
65+ def remove_datasource (self , datasource_name : str ) -> None :
14666 """
147- Delete datasource from mind
148-
149- Datasource can be passed as
150- - name, str
151- - Datasource object (minds.datasources.Database)
67+ Remove a datasource from a Mind.
15268
153- :param datasource: datasource to delete
69+ :param datasource_name: name of the datasource to remove.
15470 """
155- if isinstance (datasource , Datasource ):
156- datasource = datasource .name
157- elif not isinstance (datasource , str ):
158- raise ValueError (f'Unknown type of datasource: { datasource } ' )
159-
160- updated_datasources = [ds for ds in (self .datasources or []) if ds ['name' ] != datasource ]
161- if len (updated_datasources ) == len (self .datasources or []):
162- raise exc .ObjectNotFound (f'Datasource { datasource } not found in mind { self .name } ' )
163-
164- self .api .put (
71+ response = self .api .put (
16572 f'/minds/{ self .name } ' ,
16673 data = {
167- 'datasources' : updated_datasources
74+ 'datasources' : [ ds for ds in ( self . datasources or []) if ds [ 'name' ] != datasource_name ]
16875 }
16976 )
170- updated = self . client . minds . get ( self . name )
171-
172- self .datasources = updated . datasources
77+ updated_mind = response . json ( )
78+ self . datasources = updated_mind [ 'datasources' ]
79+ self .status = updated_mind [ 'status' ]
17380
17481 # def add_knowledge_base(self, knowledge_base: Union[str, KnowledgeBase, KnowledgeBaseConfig]):
17582 # """
@@ -224,7 +131,11 @@ def completion(self, message: str, stream: bool = False) -> Union[str, Iterable[
224131
225132 :return: string if stream mode is off or iterator of strings if stream mode is on
226133 """
227- response = self .openai_client .chat .completions .create (
134+ openai_client = OpenAI (
135+ api_key = self .api .api_key ,
136+ base_url = self .api .base_url
137+ )
138+ response = openai_client .chat .completions .create (
228139 model = self .name ,
229140 messages = [
230141 {'role' : 'user' , 'content' : message }
@@ -236,7 +147,7 @@ def completion(self, message: str, stream: bool = False) -> Union[str, Iterable[
236147 else :
237148 return response .choices [0 ].message .content
238149
239- def _stream_response (self , response ):
150+ def _stream_response (self , response ) -> Iterable [ str ] :
240151 for chunk in response :
241152 yield chunk .choices [0 ].delta .content
242153
@@ -252,7 +163,6 @@ def list(self) -> List[Mind]:
252163
253164 :return: iterable
254165 """
255-
256166 data = self .api .get (f'/minds' ).json ()
257167 minds_list = []
258168 for item in data :
@@ -266,32 +176,9 @@ def get(self, name: str) -> Mind:
266176 :param name: name of the mind
267177 :return: a mind object
268178 """
269-
270179 item = self .api .get (f'/minds/{ name } ' ).json ()
271180 return Mind (self .client , ** item )
272181
273- def _check_datasource (self , ds ) -> dict :
274- if isinstance (ds , DatabaseConfigBase ):
275- res = {'name' : ds .name }
276-
277- if isinstance (ds , DatabaseTables ):
278- if ds .tables :
279- res ['tables' ] = ds .tables
280-
281- if isinstance (ds , DatabaseConfig ):
282- # if not exists - create
283- try :
284- self .client .datasources .get (ds .name )
285- except exc .ObjectNotFound :
286- self .client .datasources .create (ds )
287-
288- elif isinstance (ds , str ):
289- res = {'name' : ds }
290- else :
291- raise ValueError (f'Unknown type of datasource: { ds } ' )
292-
293- return res
294-
295182 # def _check_knowledge_base(self, knowledge_base) -> str:
296183 # if isinstance(knowledge_base, KnowledgeBase):
297184 # knowledge_base = knowledge_base.name
@@ -309,22 +196,20 @@ def _check_datasource(self, ds) -> dict:
309196
310197 def create (
311198 self ,
312- name ,
313- model_name = None ,
314- provider = None ,
315- datasources = None ,
199+ name : str ,
200+ model_name : Optional [ str ] = None ,
201+ provider : Optional [ str ] = None ,
202+ datasources : Optional [ List [ Dict [ str , Union [ str , List [ str ]]]]] = None ,
316203 # knowledge_bases=None,
317204 parameters = None ,
318205 replace = False ,
319- update = False ,
320206 ) -> Mind :
321207 """
322208 Create a new mind and return it
323209
324- Datasource can be passed as
325- - name, str
326- - Datasource object (minds.datasources.Database)
327- - datasource config (minds.datasources.DatabaseConfig), in this case datasource will be created
210+ Datasources should be a list of dicts with keys:
211+ - name: str
212+ - tables: Optional[List[str]]
328213
329214 Knowledge base can be passed as
330215 - name, str
@@ -338,12 +223,9 @@ def create(
338223 :param knowledge_bases: alter list of knowledge bases used by mind, optional
339224 :param parameters, dict: other parameters of the mind, optional
340225 :param replace: if true - to remove existing mind, default is false
341- :param update: if true - to update mind if exists, default is false
342226 :return: created mind
343227 """
344-
345- if name is not None :
346- utils .validate_mind_name (name )
228+ utils .validate_mind_name (name )
347229
348230 if replace :
349231 try :
@@ -352,48 +234,81 @@ def create(
352234 except exc .ObjectNotFound :
353235 ...
354236
355- ds_list = []
356- if datasources :
357- for ds in datasources :
358- ds_list .append (self ._check_datasource (ds ))
359-
360237 # kb_names = []
361238 # if knowledge_bases:
362239 # for kb in knowledge_bases:
363240 # kb = self._check_knowledge_base(kb)
364241 # kb_names.append(kb)
365242
366- if update :
367- method = self .api .put
368- url = f'/minds/{ name } '
369- else :
370- method = self .api .post
371- url = f'/minds'
372-
373243 data = {
374244 'name' : name ,
375245 'model_name' : model_name ,
376246 'provider' : provider ,
377- 'datasources' : ds_list ,
247+ 'datasources' : datasources or [] ,
378248 }
379249 if parameters :
380250 data ['parameters' ] = parameters
381251 # if kb_names:
382252 # data['knowledge_bases'] = kb_names
383253
384- method (
385- url ,
254+ response = self .api .post (
255+ '/minds' ,
256+ data = data
257+ )
258+
259+ return Mind (self .client , ** response .json ())
260+
261+ def update (
262+ self ,
263+ name : str ,
264+ new_name : Optional [str ] = None ,
265+ model_name : Optional [str ] = None ,
266+ provider : Optional [str ] = None ,
267+ datasources : Optional [List [Dict [str , Union [str , List [str ]]]]] = None ,
268+ parameters : Optional [Dict ] = None ,
269+ ) -> Mind :
270+ """
271+ Update an existing Mind and return it
272+
273+ Datasources should be a list of dicts with keys:
274+ - name: str
275+ - tables: Optional[List[str]]
276+
277+ :param name: name of the mind to update
278+ :param new_name: new name of the mind, optional
279+ :param model_name: llm model name, optional
280+ :param provider: llm provider, optional
281+ :param datasources: list of datasources used by mind, optional
282+ :param parameters, dict: other parameters of the mind, optional
283+ :return: updated mind
284+ """
285+ utils .validate_mind_name (name )
286+ if new_name :
287+ utils .validate_mind_name (new_name )
288+
289+ data = {}
290+ if new_name :
291+ data ['name' ] = new_name
292+ if model_name is not None :
293+ data ['model_name' ] = model_name
294+ if provider is not None :
295+ data ['provider' ] = provider
296+ if datasources is not None :
297+ data ['datasources' ] = datasources
298+ if parameters is not None :
299+ data ['parameters' ] = parameters
300+
301+ response = self .api .put (
302+ f'/minds/{ name } ' ,
386303 data = data
387304 )
388- mind = self .get (name )
389305
390- return mind
306+ return Mind ( self . client , ** response . json ())
391307
392- def drop (self , name : str ):
308+ def drop (self , name : str ) -> None :
393309 """
394310 Drop mind by name
395311
396312 :param name: name of the mind
397313 """
398-
399314 self .api .delete (f'/minds/{ name } ' )
0 commit comments