Skip to content

Commit 69cd5c0

Browse files
authored
Merge pull request #20 from oracle/dev/v1.2.2
1.2.2
2 parents 8fa7585 + 86a8bce commit 69cd5c0

14 files changed

Lines changed: 240 additions & 50 deletions

File tree

‎samples/agent/tool_delete.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,4 @@
2121

2222
select_ai.connect(user=user, password=password, dsn=dsn)
2323

24-
tool = select_ai.agent.Tool("LLM_CHAT_TOOL")
25-
tool.delete(force=True)
24+
select_ai.agent.Tool.delete_tool("LLM_CHAT_TOOL", force=True)

‎samples/profile_delete.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,4 @@
1818
dsn = os.getenv("SELECT_AI_DB_CONNECT_STRING")
1919

2020
select_ai.connect(user=user, password=password, dsn=dsn)
21-
profile = select_ai.Profile(profile_name="oci_ai_profile")
22-
profile.delete()
21+
profile = select_ai.Profile.delete_profile(profile_name="oci_ai_profile")

‎src/select_ai/agent/core.py‎

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# ------------------------------------------------------------------------------
1+
# -----------------------------------------------------------------------------
22
# Copyright (c) 2025, Oracle and/or its affiliates.
33
#
44
# Licensed under the Universal Permissive License v 1.0 as shown at
@@ -173,11 +173,23 @@ def delete(self, force: Optional[bool] = False):
173173
},
174174
)
175175

176+
@classmethod
177+
def delete_agent(cls, agent_name: str, force: Optional[bool] = False):
178+
"""
179+
Class method to delete AI Agent from the database
180+
181+
:param str agent_name: The name of the AI Agent
182+
:param bool force: Force the deletion. Default value is False.
183+
184+
"""
185+
agent = cls(agent_name=agent_name)
186+
agent.delete(force=force)
187+
176188
def disable(self):
177189
"""
178190
Disable AI Agent
179191
"""
180-
with cursor as cr:
192+
with cursor() as cr:
181193
cr.callproc(
182194
"DBMS_CLOUD_AI_AGENT.DISABLE_AGENT",
183195
keyword_parameters={
@@ -189,7 +201,7 @@ def enable(self):
189201
"""
190202
Enable AI Agent
191203
"""
192-
with cursor as cr:
204+
with cursor() as cr:
193205
cr.callproc(
194206
"DBMS_CLOUD_AI_AGENT.ENABLE_AGENT",
195207
keyword_parameters={
@@ -390,11 +402,25 @@ async def delete(self, force: Optional[bool] = False):
390402
},
391403
)
392404

405+
@classmethod
406+
async def delete_agent(
407+
cls, agent_name: str, force: Optional[bool] = False
408+
):
409+
"""
410+
Class method to delete AI Agent from the database
411+
412+
:param str agent_name: The name of the AI Agent
413+
:param bool force: Force the deletion. Default value is False.
414+
415+
"""
416+
agent = cls(agent_name=agent_name)
417+
await agent.delete(force=force)
418+
393419
async def disable(self):
394420
"""
395421
Disable AI Agent
396422
"""
397-
async with async_cursor as cr:
423+
async with async_cursor() as cr:
398424
await cr.callproc(
399425
"DBMS_CLOUD_AI_AGENT.DISABLE_AGENT",
400426
keyword_parameters={
@@ -406,7 +432,7 @@ async def enable(self):
406432
"""
407433
Enable AI Agent
408434
"""
409-
async with async_cursor as cr:
435+
async with async_cursor() as cr:
410436
await cr.callproc(
411437
"DBMS_CLOUD_AI_AGENT.ENABLE_AGENT",
412438
keyword_parameters={

‎src/select_ai/agent/task.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ def delete(self, force: bool = False):
188188
},
189189
)
190190

191+
@classmethod
192+
def delete_task(cls, task_name: str, force: bool = False):
193+
"""
194+
Class method to delete AI Task from the database
195+
196+
:param str task_name: The name of the AI Task
197+
:param bool force: Force the deletion. Default value is False.
198+
"""
199+
task = cls(task_name=task_name)
200+
task.delete(force=force)
201+
191202
def disable(self):
192203
"""
193204
Disable AI Task
@@ -406,6 +417,17 @@ async def delete(self, force: bool = False):
406417
},
407418
)
408419

420+
@classmethod
421+
async def delete_task(cls, task_name: str, force: bool = False):
422+
"""
423+
Class method to delete AI Task from the database
424+
425+
:param str task_name: The name of the AI Task
426+
:param bool force: Force the deletion. Default value is False.
427+
"""
428+
task = cls(task_name=task_name)
429+
await task.delete(force=force)
430+
409431
async def disable(self):
410432
"""
411433
Disable AI Task

‎src/select_ai/agent/team.py‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ class BaseTeam(ABC):
5757
def __init__(
5858
self,
5959
team_name: str,
60-
attributes: TeamAttributes,
60+
attributes: Optional[TeamAttributes] = None,
6161
description: Optional[str] = None,
6262
):
63-
if not isinstance(attributes, TeamAttributes):
63+
if attributes and not isinstance(attributes, TeamAttributes):
6464
raise TypeError(
6565
f"attributes must be an object of type "
6666
f"select_ai.agent.TeamAttributes instance"
@@ -180,6 +180,17 @@ def delete(self, force: Optional[bool] = False):
180180
},
181181
)
182182

183+
@classmethod
184+
def delete_team(cls, team_name: str, force: Optional[bool] = False):
185+
"""
186+
Class method to delete an AI agent team from the database
187+
188+
:param str team_name: The name of the AI team
189+
:param bool force: Force the deletion. Default value is False.
190+
"""
191+
team = cls(team_name=team_name)
192+
team.delete(force=force)
193+
183194
def disable(self):
184195
"""
185196
Disable the AI agent team
@@ -435,6 +446,17 @@ async def delete(self, force: Optional[bool] = False):
435446
},
436447
)
437448

449+
@classmethod
450+
async def delete_team(cls, team_name: str, force: Optional[bool] = False):
451+
"""
452+
Class method to delete an AI agent team from the database
453+
454+
:param str team_name: The name of the AI team
455+
:param bool force: Force the deletion. Default value is False.
456+
"""
457+
team = cls(team_name=team_name)
458+
await team.delete(force=force)
459+
438460
async def disable(self):
439461
"""
440462
Disable the AI agent team

‎src/select_ai/agent/tool.py‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@ class ToolType(StrEnum):
4848
Built-in Tool Types
4949
"""
5050

51-
EMAIL = "EMAIL"
5251
HUMAN = "HUMAN"
5352
HTTP = "HTTP"
5453
RAG = "RAG"
5554
SQL = "SQL"
56-
SLACK = "SLACK"
5755
WEBSEARCH = "WEBSEARCH"
56+
NOTIFICATION = "NOTIFICATION"
5857

5958

6059
@dataclass
@@ -103,6 +102,12 @@ def __post_init__(self):
103102
@classmethod
104103
def create(cls, *, tool_type: Optional[ToolType] = None, **kwargs):
105104
tool_params_cls = ToolTypeParams.get(tool_type, ToolParams)
105+
if "notification_type" in kwargs:
106+
notification_type = kwargs["notification_type"]
107+
if notification_type == NotificationType.SLACK:
108+
tool_params_cls = SlackNotificationToolParams
109+
elif notification_type == NotificationType.EMAIL:
110+
tool_params_cls = EmailNotificationToolParams
106111
return tool_params_cls(**kwargs)
107112

108113
@classmethod
@@ -132,14 +137,20 @@ class RAGToolParams(ToolParams):
132137

133138

134139
@dataclass
135-
class SlackNotificationToolParams(ToolParams):
140+
class NotificationToolParams(ToolParams):
141+
142+
notification_type = NotificationType
143+
144+
145+
@dataclass
146+
class SlackNotificationToolParams(NotificationToolParams):
136147

137148
_REQUIRED_FIELDS = ["credential_name", "slack_channel"]
138149
notification_type: NotificationType = NotificationType.SLACK
139150

140151

141152
@dataclass
142-
class EmailNotificationToolParams(ToolParams):
153+
class EmailNotificationToolParams(NotificationToolParams):
143154

144155
_REQUIRED_FIELDS = ["credential_name", "recipient", "sender", "smtp_host"]
145156
notification_type: NotificationType = NotificationType.EMAIL
@@ -222,8 +233,7 @@ def create(cls, **kwargs):
222233

223234

224235
ToolTypeParams = {
225-
ToolType.EMAIL: EmailNotificationToolParams,
226-
ToolType.SLACK: SlackNotificationToolParams,
236+
ToolType.NOTIFICATION: NotificationToolParams,
227237
ToolType.HTTP: HTTPToolParams,
228238
ToolType.RAG: RAGToolParams,
229239
ToolType.SQL: SQLToolParams,
@@ -401,7 +411,7 @@ def create_email_notification_tool(
401411
)
402412
return cls.create_built_in_tool(
403413
tool_name=tool_name,
404-
tool_type=ToolType.EMAIL,
414+
tool_type=ToolType.NOTIFICATION,
405415
tool_params=email_notification_tool_params,
406416
description=description,
407417
replace=replace,
@@ -534,7 +544,7 @@ def create_slack_notification_tool(
534544
)
535545
return cls.create_built_in_tool(
536546
tool_name=tool_name,
537-
tool_type=ToolType.SLACK,
547+
tool_type=ToolType.NOTIFICATION,
538548
tool_params=slack_notification_tool_params,
539549
description=description,
540550
replace=replace,
@@ -585,6 +595,17 @@ def delete(self, force: bool = False):
585595
},
586596
)
587597

598+
@classmethod
599+
def delete_tool(cls, tool_name: str, force: bool = False):
600+
"""
601+
Class method to delete AI Tool from the database
602+
603+
:param str tool_name: The name of the tool
604+
:param bool force: Force the deletion. Default value is False.
605+
"""
606+
tool = cls(tool_name=tool_name)
607+
tool.delete(force=force)
608+
588609
def disable(self):
589610
"""
590611
Disable AI Tool
@@ -835,7 +856,7 @@ async def create_email_notification_tool(
835856
)
836857
return await cls.create_built_in_tool(
837858
tool_name=tool_name,
838-
tool_type=ToolType.EMAIL,
859+
tool_type=ToolType.NOTIFICATION,
839860
tool_params=email_notification_tool_params,
840861
description=description,
841862
replace=replace,
@@ -968,7 +989,7 @@ async def create_slack_notification_tool(
968989
)
969990
return await cls.create_built_in_tool(
970991
tool_name=tool_name,
971-
tool_type=ToolType.SLACK,
992+
tool_type=ToolType.NOTIFICATION,
972993
tool_params=slack_notification_tool_params,
973994
description=description,
974995
replace=replace,
@@ -1019,6 +1040,17 @@ async def delete(self, force: bool = False):
10191040
},
10201041
)
10211042

1043+
@classmethod
1044+
async def delete_tool(cls, tool_name: str, force: bool = False):
1045+
"""
1046+
Class method ot delete AI Tool from the database
1047+
1048+
:param str tool_name: The name of the tool
1049+
:param bool force: Force the deletion. Default value is False.
1050+
"""
1051+
tool = cls(tool_name=tool_name)
1052+
await tool.delete(force=force)
1053+
10221054
async def disable(self):
10231055
"""
10241056
Disable AI Tool

‎src/select_ai/async_profile.py‎

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from select_ai.base_profile import (
2424
BaseProfile,
2525
ProfileAttributes,
26-
no_data_for_prompt,
26+
convert_json_rows_to_df,
2727
validate_params_for_feedback,
2828
validate_params_for_summary,
2929
)
@@ -248,23 +248,40 @@ async def create(self, replace: Optional[int] = False) -> None:
248248
else:
249249
raise
250250

251-
async def delete(self, force=False) -> None:
252-
"""Asynchronously deletes an AI profile from the database
253-
254-
:param bool force: Ignores errors if AI profile does not exist.
255-
:return: None
256-
:raises: oracledb.DatabaseError
257-
251+
@staticmethod
252+
async def _delete(profile_name: str, force: bool = False):
253+
"""
254+
Internal method to delete AI profile from the database
258255
"""
259256
async with async_cursor() as cr:
260257
await cr.callproc(
261258
"DBMS_CLOUD_AI.DROP_PROFILE",
262259
keyword_parameters={
263-
"profile_name": self.profile_name,
260+
"profile_name": profile_name,
264261
"force": force,
265262
},
266263
)
267264

265+
async def delete(self, force=False) -> None:
266+
"""Asynchronously deletes an AI profile from the database
267+
268+
:param bool force: Ignores errors if AI profile does not exist.
269+
:return: None
270+
:raises: oracledb.DatabaseError
271+
"""
272+
await self._delete(profile_name=self.profile_name, force=force)
273+
274+
@classmethod
275+
async def delete_profile(cls, profile_name: str, force: bool = False):
276+
"""Asynchronously deletes an AI profile from the database
277+
278+
:param str profile_name: Name of the AI profile
279+
:param bool force: Ignores errors if AI profile does not exist.
280+
:return: None
281+
:raises: oracledb.DatabaseError
282+
"""
283+
await cls._delete(profile_name=profile_name, force=force)
284+
268285
@classmethod
269286
async def fetch(cls, profile_name: str) -> "AsyncProfile":
270287
"""Asynchronously create an AI Profile object from attributes
@@ -423,9 +440,7 @@ async def generate(
423440
else:
424441
result = None
425442
if action == Action.RUNSQL:
426-
if no_data_for_prompt(result): # empty dataframe
427-
return pandas.DataFrame()
428-
return pandas.DataFrame(json.loads(result))
443+
return convert_json_rows_to_df(result)
429444
else:
430445
return result
431446

0 commit comments

Comments
 (0)