Skip to content

Commit d80e0ab

Browse files
committed
Added test cases for Select AI agents
1 parent 64d1031 commit d80e0ab

File tree

9 files changed

+323
-18
lines changed

9 files changed

+323
-18
lines changed

samples/agent/task_create.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
task = Task(
2727
task_name="ANALYZE_MOVIE_TASK",
28-
description="Movie task involving a human",
28+
description="Search for movies in the database",
2929
attributes=TaskAttributes(
3030
instruction="Help the user with their request about movies. "
3131
"User question: {query}. "

src/select_ai/_abc.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ def _bool(value: Any) -> bool:
2727
raise ValueError(f"Invalid boolean value: {value}")
2828

2929

30+
def _is_json(field, value) -> bool:
31+
if field.type in (
32+
typing.List[Mapping],
33+
typing.Optional[Mapping],
34+
typing.Optional[List[str]],
35+
typing.Optional[List[typing.Mapping]],
36+
) and isinstance(value, (str, bytes, bytearray)):
37+
return True
38+
return False
39+
40+
3041
@dataclass
3142
class SelectAIDataClass(ABC):
3243
"""SelectAIDataClass is an abstract container for all data
@@ -65,13 +76,7 @@ def __post_init__(self):
6576
setattr(self, field.name, _bool(value))
6677
elif field.type is typing.Optional[float]:
6778
setattr(self, field.name, float(value))
68-
elif field.type is typing.Optional[Mapping] and isinstance(
69-
value, (str, bytes, bytearray)
70-
):
71-
setattr(self, field.name, json.loads(value))
72-
elif field.type is typing.Optional[
73-
List[typing.Mapping]
74-
] and isinstance(value, (str, bytes, bytearray)):
79+
elif _is_json(field, value):
7580
setattr(self, field.name, json.loads(value))
7681
else:
7782
setattr(self, field.name, value)

src/select_ai/agent/sql.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,21 @@
6262

6363

6464
GET_USER_AI_AGENT_TEAM = """
65-
SELECT t.tool_name, t.description
65+
SELECT t.agent_team_name as team_name, t.description
6666
FROM USER_AI_AGENT_TEAMS t
67-
WHERE t.team_name = :team_name
67+
WHERE t.agent_team_name = :team_name
6868
"""
6969

70+
7071
GET_USER_AI_AGENT_TEAM_ATTRIBUTES = """
7172
SELECT attribute_name, attribute_value
7273
FROM USER_AI_AGENT_TEAM_ATTRIBUTES
73-
WHERE team_name = :team_name
74+
WHERE agent_team_name = :team_name
7475
"""
7576

77+
7678
LIST_USER_AI_AGENT_TEAMS = """
77-
SELECT t.tool_name, t.description
79+
SELECT t.AGENT_TEAM_NAME as team_name, description
7880
FROM USER_AI_AGENT_TEAMS t
79-
WHERE REGEXP_LIKE(t.team_name, :team_name_pattern, 'i')
81+
WHERE REGEXP_LIKE(t.AGENT_TEAM_NAME, :team_name_pattern, 'i')
8082
"""

src/select_ai/agent/team.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def _get_attributes(team_name: str) -> TeamAttributes:
110110
@staticmethod
111111
def _get_description(team_name: str) -> Union[str, None]:
112112
with cursor() as cr:
113-
cr.execute(GET_USER_AI_AGENT_TEAM, task_name=team_name.upper())
113+
cr.execute(GET_USER_AI_AGENT_TEAM, team_name=team_name.upper())
114114
team = cr.fetchone()
115115
if team:
116116
if team[1] is not None:

tests/agents/test_3000_tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# -----------------------------------------------------------------------------
77

88
"""
9-
3000 - Module for testing select_ai agents
9+
3000 - Module for testing select_ai agent tools
1010
"""
1111

1212
import uuid

tests/agents/test_3100_tasks.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (c) 2025, Oracle and/or its affiliates.
3+
#
4+
# Licensed under the Universal Permissive License v 1.0 as shown at
5+
# http://oss.oracle.com/licenses/upl.
6+
# -----------------------------------------------------------------------------
7+
8+
"""
9+
3100 - Module for testing select_ai agent tasks
10+
"""
11+
12+
import uuid
13+
14+
import pytest
15+
import select_ai
16+
from select_ai.agent import Task, TaskAttributes
17+
18+
PYSAI_3100_TASK_NAME = f"PYSAI_3100_{uuid.uuid4().hex.upper()}"
19+
PYSAI_3100_SQL_TASK_DESCRIPTION = "PYSAI_3100_SQL_TASK_DESCRIPTION"
20+
21+
22+
@pytest.fixture(scope="module")
23+
def task_attributes():
24+
return TaskAttributes(
25+
instruction="Help the user with their request about movies. "
26+
"User question: {query}. "
27+
"You can use SQL tool to search the data from database",
28+
tools=["MOVIE_SQL_TOOL"],
29+
enable_human_tool=False,
30+
)
31+
32+
33+
@pytest.fixture(scope="module")
34+
def task(task_attributes):
35+
task = Task(
36+
task_name=PYSAI_3100_TASK_NAME,
37+
description=PYSAI_3100_SQL_TASK_DESCRIPTION,
38+
attributes=task_attributes,
39+
)
40+
task.create()
41+
yield task
42+
task.delete(force=True)
43+
44+
45+
def test_3100(task, task_attributes):
46+
"""simple task creation"""
47+
assert task.task_name == PYSAI_3100_TASK_NAME
48+
assert task.attributes == task_attributes
49+
assert task.description == PYSAI_3100_SQL_TASK_DESCRIPTION
50+
51+
52+
@pytest.mark.parametrize("task_name_pattern", [None, "^PYSAI_3100_"])
53+
def test_3101(task_name_pattern):
54+
"""task list"""
55+
if task_name_pattern:
56+
tasks = list(select_ai.agent.Task.list(task_name_pattern))
57+
else:
58+
tasks = list(select_ai.agent.Task.list())
59+
task_names = set(task.task_name for task in tasks)
60+
task_descriptions = set(task.description for task in tasks)
61+
assert PYSAI_3100_TASK_NAME in task_names
62+
assert PYSAI_3100_SQL_TASK_DESCRIPTION in task_descriptions
63+
64+
65+
def test_3102(task_attributes):
66+
"""task fetch"""
67+
task = select_ai.agent.Task.fetch(PYSAI_3100_TASK_NAME)
68+
assert task.task_name == PYSAI_3100_TASK_NAME
69+
assert task.attributes == task_attributes
70+
assert task.description == PYSAI_3100_SQL_TASK_DESCRIPTION

tests/agents/test_3200_agents.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (c) 2025, Oracle and/or its affiliates.
3+
#
4+
# Licensed under the Universal Permissive License v 1.0 as shown at
5+
# http://oss.oracle.com/licenses/upl.
6+
# -----------------------------------------------------------------------------
7+
8+
"""
9+
3200 - Module for testing select_ai agents
10+
"""
11+
import uuid
12+
13+
import pytest
14+
import select_ai
15+
from select_ai.agent import Agent, AgentAttributes
16+
17+
PYSAI_3200_AGENT_NAME = f"PYSAI_3200_AGENT_{uuid.uuid4().hex.upper()}"
18+
PYSAI_3200_AGENT_DESCRIPTION = "PYSAI_3200_AGENT_DESCRIPTION"
19+
PYSAI_3200_PROFILE_NAME = f"PYSAI_3200_PROFILE_{uuid.uuid4().hex.upper()}"
20+
21+
22+
@pytest.fixture(scope="module")
23+
def python_gen_ai_profile(profile_attributes):
24+
profile = select_ai.Profile(
25+
profile_name=PYSAI_3200_PROFILE_NAME,
26+
description="OCI GENAI Profile",
27+
attributes=profile_attributes,
28+
)
29+
yield profile
30+
profile.delete(force=True)
31+
32+
33+
@pytest.fixture(scope="module")
34+
def agent_attributes():
35+
agent_attributes = AgentAttributes(
36+
profile_name=PYSAI_3200_PROFILE_NAME,
37+
role="You are an AI Movie Analyst. "
38+
"Your can help answer a variety of questions related to movies. ",
39+
enable_human_tool=False,
40+
)
41+
return agent_attributes
42+
43+
44+
@pytest.fixture(scope="module")
45+
def agent(python_gen_ai_profile, agent_attributes):
46+
agent = Agent(
47+
agent_name=PYSAI_3200_AGENT_NAME,
48+
attributes=agent_attributes,
49+
description=PYSAI_3200_AGENT_DESCRIPTION,
50+
)
51+
agent.create(enabled=True, replace=True)
52+
yield agent
53+
agent.delete(force=True)
54+
55+
56+
def test_3200(agent, agent_attributes):
57+
assert agent.agent_name == PYSAI_3200_AGENT_NAME
58+
assert agent.attributes == agent_attributes
59+
assert agent.description == PYSAI_3200_AGENT_DESCRIPTION
60+
61+
62+
@pytest.mark.parametrize("agent_name_pattern", [None, "^PYSAI_3200_AGENT_"])
63+
def test_3201(agent_name_pattern):
64+
if agent_name_pattern:
65+
agents = list(select_ai.agent.Agent.list(agent_name_pattern))
66+
else:
67+
agents = list(select_ai.agent.Agent.list())
68+
agent_names = set(agent.agent_name for agent in agents)
69+
agent_descriptions = set(agent.description for agent in agents)
70+
assert PYSAI_3200_AGENT_NAME in agent_names
71+
assert PYSAI_3200_AGENT_DESCRIPTION in agent_descriptions

tests/agents/test_3300_teams.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (c) 2025, Oracle and/or its affiliates.
3+
#
4+
# Licensed under the Universal Permissive License v 1.0 as shown at
5+
# http://oss.oracle.com/licenses/upl.
6+
# -----------------------------------------------------------------------------
7+
8+
"""
9+
3300 - Module for testing select_ai agent teams
10+
"""
11+
12+
import uuid
13+
14+
import pytest
15+
import select_ai
16+
from select_ai.agent import (
17+
Agent,
18+
AgentAttributes,
19+
Task,
20+
TaskAttributes,
21+
Team,
22+
TeamAttributes,
23+
)
24+
25+
PYSAI_3300_AGENT_NAME = f"PYSAI_3300_AGENT_{uuid.uuid4().hex.upper()}"
26+
PYSAI_3300_AGENT_DESCRIPTION = "PYSAI_3300_AGENT_DESCRIPTION"
27+
PYSAI_3300_PROFILE_NAME = f"PYSAI_3300_PROFILE_{uuid.uuid4().hex.upper()}"
28+
PYSAI_3300_TASK_NAME = f"PYSAI_3300_{uuid.uuid4().hex.upper()}"
29+
PYSAI_3300_TASK_DESCRIPTION = "PYSAI_3100_SQL_TASK_DESCRIPTION"
30+
PYSAI_3300_TEAM_NAME = f"PYSAI_3300_TEAM_{uuid.uuid4().hex.upper()}"
31+
PYSAI_3300_TEAM_DESCRIPTION = "PYSAI_3300_TEAM_DESCRIPTION"
32+
33+
34+
@pytest.fixture(scope="module")
35+
def python_gen_ai_profile(profile_attributes):
36+
profile = select_ai.Profile(
37+
profile_name=PYSAI_3300_PROFILE_NAME,
38+
description="OCI GENAI Profile",
39+
attributes=profile_attributes,
40+
)
41+
yield profile
42+
profile.delete(force=True)
43+
44+
45+
@pytest.fixture(scope="module")
46+
def task_attributes():
47+
return TaskAttributes(
48+
instruction="Help the user with their request about movies. "
49+
"User question: {query}. ",
50+
enable_human_tool=False,
51+
)
52+
53+
54+
@pytest.fixture(scope="module")
55+
def task(task_attributes):
56+
task = Task(
57+
task_name=PYSAI_3300_TASK_NAME,
58+
description=PYSAI_3300_TASK_DESCRIPTION,
59+
attributes=task_attributes,
60+
)
61+
task.create()
62+
yield task
63+
task.delete(force=True)
64+
65+
66+
@pytest.fixture(scope="module")
67+
def agent(python_gen_ai_profile):
68+
agent = Agent(
69+
agent_name=PYSAI_3300_AGENT_NAME,
70+
description=PYSAI_3300_AGENT_DESCRIPTION,
71+
attributes=AgentAttributes(
72+
profile_name=PYSAI_3300_PROFILE_NAME,
73+
role="You are an AI Movie Analyst. "
74+
"Your can help answer a variety of questions related to movies. ",
75+
enable_human_tool=False,
76+
),
77+
)
78+
agent.create(enabled=True, replace=True)
79+
yield agent
80+
agent.delete(force=True)
81+
82+
83+
@pytest.fixture(scope="module")
84+
def team_attributes(agent, task):
85+
return TeamAttributes(
86+
agents=[{"name": agent.agent_name, "task": task.task_name}],
87+
process="sequential",
88+
)
89+
90+
91+
@pytest.fixture(scope="module")
92+
def team(team_attributes):
93+
team = Team(
94+
team_name=PYSAI_3300_TEAM_NAME,
95+
description=PYSAI_3300_TEAM_DESCRIPTION,
96+
attributes=team_attributes,
97+
)
98+
team.create()
99+
yield team
100+
team.delete(force=True)
101+
102+
103+
def test_3300(team, team_attributes):
104+
assert team.team_name == PYSAI_3300_TEAM_NAME
105+
assert team.description == PYSAI_3300_TEAM_DESCRIPTION
106+
assert team.attributes == team_attributes
107+
108+
109+
@pytest.mark.parametrize("team_name_pattern", [None, "^PYSAI_3300_TEAM_"])
110+
def test_3301(team_name_pattern):
111+
if team_name_pattern:
112+
teams = list(select_ai.agent.Team.list(team_name_pattern))
113+
else:
114+
teams = list(select_ai.agent.Team.list())
115+
team_names = set(team.team_name for team in teams)
116+
team_descriptions = set(team.description for team in teams)
117+
assert PYSAI_3300_TEAM_NAME in team_names
118+
assert PYSAI_3300_TEAM_DESCRIPTION in team_descriptions
119+
120+
121+
def test_3302(team_attributes):
122+
team = select_ai.agent.Team.fetch(team_name=PYSAI_3300_TEAM_NAME)
123+
assert team.team_name == PYSAI_3300_TEAM_NAME
124+
assert team.description == PYSAI_3300_TEAM_DESCRIPTION
125+
assert team.attributes == team_attributes

0 commit comments

Comments
 (0)