select-ai 1.2.0rc3__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.
- select_ai/__init__.py +66 -0
- select_ai/_abc.py +82 -0
- select_ai/_enums.py +14 -0
- select_ai/_validations.py +123 -0
- select_ai/action.py +23 -0
- select_ai/agent/__init__.py +25 -0
- select_ai/agent/core.py +511 -0
- select_ai/agent/sql.py +82 -0
- select_ai/agent/task.py +521 -0
- select_ai/agent/team.py +590 -0
- select_ai/agent/tool.py +1129 -0
- select_ai/async_profile.py +648 -0
- select_ai/base_profile.py +265 -0
- select_ai/conversation.py +295 -0
- select_ai/credential.py +135 -0
- select_ai/db.py +191 -0
- select_ai/errors.py +113 -0
- select_ai/feedback.py +19 -0
- select_ai/privilege.py +135 -0
- select_ai/profile.py +579 -0
- select_ai/provider.py +195 -0
- select_ai/sql.py +111 -0
- select_ai/summary.py +61 -0
- select_ai/synthetic_data.py +90 -0
- select_ai/vector_index.py +642 -0
- select_ai/version.py +8 -0
- select_ai-1.2.0rc3.dist-info/METADATA +129 -0
- select_ai-1.2.0rc3.dist-info/RECORD +31 -0
- select_ai-1.2.0rc3.dist-info/WHEEL +5 -0
- select_ai-1.2.0rc3.dist-info/licenses/LICENSE.txt +35 -0
- select_ai-1.2.0rc3.dist-info/top_level.txt +1 -0
select_ai/agent/task.py
ADDED
|
@@ -0,0 +1,521 @@
|
|
|
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
|
+
import json
|
|
9
|
+
from abc import ABC
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from typing import (
|
|
12
|
+
Any,
|
|
13
|
+
AsyncGenerator,
|
|
14
|
+
Iterator,
|
|
15
|
+
List,
|
|
16
|
+
Mapping,
|
|
17
|
+
Optional,
|
|
18
|
+
Union,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
import oracledb
|
|
22
|
+
|
|
23
|
+
from select_ai import BaseProfile
|
|
24
|
+
from select_ai._abc import SelectAIDataClass
|
|
25
|
+
from select_ai._enums import StrEnum
|
|
26
|
+
from select_ai.agent.sql import (
|
|
27
|
+
GET_USER_AI_AGENT_TASK,
|
|
28
|
+
GET_USER_AI_AGENT_TASK_ATTRIBUTES,
|
|
29
|
+
LIST_USER_AI_AGENT_TASKS,
|
|
30
|
+
)
|
|
31
|
+
from select_ai.async_profile import AsyncProfile
|
|
32
|
+
from select_ai.db import async_cursor, cursor
|
|
33
|
+
from select_ai.errors import AgentTaskNotFoundError
|
|
34
|
+
from select_ai.profile import Profile
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class TaskAttributes(SelectAIDataClass):
|
|
39
|
+
"""AI Task attributes
|
|
40
|
+
|
|
41
|
+
:param str instruction: Statement describing what the task is
|
|
42
|
+
meant to accomplish
|
|
43
|
+
|
|
44
|
+
:param List[str] tools: List of tools the agent can use to
|
|
45
|
+
execute the task
|
|
46
|
+
|
|
47
|
+
:param str input: Task name whose output will be automatically
|
|
48
|
+
provided by select ai to LLM
|
|
49
|
+
|
|
50
|
+
:param bool enable_human_tool: Enable agent to ask question
|
|
51
|
+
to user when it requires information or clarification
|
|
52
|
+
during a task. Default value is True.
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
instruction: str
|
|
57
|
+
tools: Optional[List[str]] = None
|
|
58
|
+
input: Optional[str] = None
|
|
59
|
+
enable_human_tool: Optional[bool] = True
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class BaseTask(ABC):
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
task_name: Optional[str] = None,
|
|
67
|
+
description: Optional[str] = None,
|
|
68
|
+
attributes: Optional[TaskAttributes] = None,
|
|
69
|
+
):
|
|
70
|
+
if attributes and not isinstance(attributes, TaskAttributes):
|
|
71
|
+
raise TypeError(
|
|
72
|
+
"'attributes' must be an object of type "
|
|
73
|
+
"select_ai.agent.TaskAttributes"
|
|
74
|
+
)
|
|
75
|
+
self.task_name = task_name
|
|
76
|
+
self.description = description
|
|
77
|
+
self.attributes = attributes
|
|
78
|
+
|
|
79
|
+
def __repr__(self):
|
|
80
|
+
return (
|
|
81
|
+
f"{self.__class__.__name__}("
|
|
82
|
+
f"task_name={self.task_name}, "
|
|
83
|
+
f"attributes={self.attributes}, description={self.description})"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class Task(BaseTask):
|
|
88
|
+
"""
|
|
89
|
+
select_ai.agent.Task class lets you create, delete, enable, disable and
|
|
90
|
+
list AI Tasks
|
|
91
|
+
|
|
92
|
+
:param str task_name: The name of the AI task
|
|
93
|
+
:param str description: Optional description of the AI task
|
|
94
|
+
:param select_ai.agent.TaskAttributes attributes: AI task attributes
|
|
95
|
+
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def _get_attributes(task_name: str) -> TaskAttributes:
|
|
100
|
+
with cursor() as cr:
|
|
101
|
+
cr.execute(
|
|
102
|
+
GET_USER_AI_AGENT_TASK_ATTRIBUTES, task_name=task_name.upper()
|
|
103
|
+
)
|
|
104
|
+
attributes = cr.fetchall()
|
|
105
|
+
if attributes:
|
|
106
|
+
post_processed_attributes = {}
|
|
107
|
+
for k, v in attributes:
|
|
108
|
+
if isinstance(v, oracledb.LOB):
|
|
109
|
+
post_processed_attributes[k] = v.read()
|
|
110
|
+
else:
|
|
111
|
+
post_processed_attributes[k] = v
|
|
112
|
+
return TaskAttributes(**post_processed_attributes)
|
|
113
|
+
else:
|
|
114
|
+
raise AgentTaskNotFoundError(task_name=task_name)
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def _get_description(task_name: str) -> Union[str, None]:
|
|
118
|
+
with cursor() as cr:
|
|
119
|
+
cr.execute(GET_USER_AI_AGENT_TASK, task_name=task_name.upper())
|
|
120
|
+
task = cr.fetchone()
|
|
121
|
+
if task:
|
|
122
|
+
if task[1] is not None:
|
|
123
|
+
return task[1].read()
|
|
124
|
+
else:
|
|
125
|
+
return None
|
|
126
|
+
else:
|
|
127
|
+
raise AgentTaskNotFoundError(task_name)
|
|
128
|
+
|
|
129
|
+
def create(
|
|
130
|
+
self, enabled: Optional[bool] = True, replace: Optional[bool] = False
|
|
131
|
+
):
|
|
132
|
+
"""
|
|
133
|
+
Create a task that a Select AI agent can include in its
|
|
134
|
+
reasoning process
|
|
135
|
+
|
|
136
|
+
:param bool enabled: Whether the AI Task should be enabled.
|
|
137
|
+
Default value is True.
|
|
138
|
+
|
|
139
|
+
:param bool replace: Whether the AI Task should be replaced.
|
|
140
|
+
Default value is False.
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
if self.task_name is None:
|
|
144
|
+
raise AttributeError("Task must have a name")
|
|
145
|
+
if self.attributes is None:
|
|
146
|
+
raise AttributeError("Task must have attributes")
|
|
147
|
+
|
|
148
|
+
parameters = {
|
|
149
|
+
"task_name": self.task_name,
|
|
150
|
+
"attributes": self.attributes.json(),
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if self.description:
|
|
154
|
+
parameters["description"] = self.description
|
|
155
|
+
|
|
156
|
+
if not enabled:
|
|
157
|
+
parameters["status"] = "disabled"
|
|
158
|
+
|
|
159
|
+
with cursor() as cr:
|
|
160
|
+
try:
|
|
161
|
+
cr.callproc(
|
|
162
|
+
"DBMS_CLOUD_AI_AGENT.CREATE_TASK",
|
|
163
|
+
keyword_parameters=parameters,
|
|
164
|
+
)
|
|
165
|
+
except oracledb.Error as err:
|
|
166
|
+
(err_obj,) = err.args
|
|
167
|
+
if err_obj.code in (20051, 20052) and replace:
|
|
168
|
+
self.delete(force=True)
|
|
169
|
+
cr.callproc(
|
|
170
|
+
"DBMS_CLOUD_AI_AGENT.CREATE_TASK",
|
|
171
|
+
keyword_parameters=parameters,
|
|
172
|
+
)
|
|
173
|
+
else:
|
|
174
|
+
raise
|
|
175
|
+
|
|
176
|
+
def delete(self, force: bool = False):
|
|
177
|
+
"""
|
|
178
|
+
Delete AI Task from the database
|
|
179
|
+
|
|
180
|
+
:param bool force: Force the deletion. Default value is False.
|
|
181
|
+
"""
|
|
182
|
+
with cursor() as cr:
|
|
183
|
+
cr.callproc(
|
|
184
|
+
"DBMS_CLOUD_AI_AGENT.DROP_TASK",
|
|
185
|
+
keyword_parameters={
|
|
186
|
+
"task_name": self.task_name,
|
|
187
|
+
"force": force,
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
def disable(self):
|
|
192
|
+
"""
|
|
193
|
+
Disable AI Task
|
|
194
|
+
"""
|
|
195
|
+
with cursor() as cr:
|
|
196
|
+
cr.callproc(
|
|
197
|
+
"DBMS_CLOUD_AI_AGENT.DISABLE_TASK",
|
|
198
|
+
keyword_parameters={
|
|
199
|
+
"task_name": self.task_name,
|
|
200
|
+
},
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def enable(self):
|
|
204
|
+
"""
|
|
205
|
+
Enable AI Task
|
|
206
|
+
"""
|
|
207
|
+
with cursor() as cr:
|
|
208
|
+
cr.callproc(
|
|
209
|
+
"DBMS_CLOUD_AI_AGENT.ENABLE_TASK",
|
|
210
|
+
keyword_parameters={
|
|
211
|
+
"task_name": self.task_name,
|
|
212
|
+
},
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
@classmethod
|
|
216
|
+
def list(cls, task_name_pattern: Optional[str] = ".*") -> Iterator["Task"]:
|
|
217
|
+
"""List AI Tasks
|
|
218
|
+
|
|
219
|
+
:param str task_name_pattern: Regular expressions can be used
|
|
220
|
+
to specify a pattern. Function REGEXP_LIKE is used to perform the
|
|
221
|
+
match. Default value is ".*" i.e. match all tasks.
|
|
222
|
+
|
|
223
|
+
:return: Iterator[Task]
|
|
224
|
+
"""
|
|
225
|
+
with cursor() as cr:
|
|
226
|
+
cr.execute(
|
|
227
|
+
LIST_USER_AI_AGENT_TASKS,
|
|
228
|
+
task_name_pattern=task_name_pattern,
|
|
229
|
+
)
|
|
230
|
+
for row in cr.fetchall():
|
|
231
|
+
task_name = row[0]
|
|
232
|
+
if row[1]:
|
|
233
|
+
description = row[1].read() # Oracle.LOB
|
|
234
|
+
else:
|
|
235
|
+
description = None
|
|
236
|
+
attributes = cls._get_attributes(task_name=task_name)
|
|
237
|
+
yield cls(
|
|
238
|
+
task_name=task_name,
|
|
239
|
+
description=description,
|
|
240
|
+
attributes=attributes,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
@classmethod
|
|
244
|
+
def fetch(cls, task_name: str) -> "Task":
|
|
245
|
+
"""
|
|
246
|
+
Fetch AI Task attributes from the Database and build a proxy object in
|
|
247
|
+
the Python layer
|
|
248
|
+
|
|
249
|
+
:param str task_name: The name of the AI Task
|
|
250
|
+
|
|
251
|
+
:return: select_ai.agent.Task
|
|
252
|
+
|
|
253
|
+
:raises select_ai.errors.AgentTaskNotFoundError:
|
|
254
|
+
If the AI Task is not found
|
|
255
|
+
"""
|
|
256
|
+
attributes = cls._get_attributes(task_name=task_name)
|
|
257
|
+
description = cls._get_description(task_name=task_name)
|
|
258
|
+
return cls(
|
|
259
|
+
task_name=task_name,
|
|
260
|
+
description=description,
|
|
261
|
+
attributes=attributes,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
def set_attributes(self, attributes: TaskAttributes):
|
|
265
|
+
"""
|
|
266
|
+
Set AI Task attributes
|
|
267
|
+
|
|
268
|
+
:param select_ai.agent.TaskAttributes attributes: Multiple attributes
|
|
269
|
+
can be specified by passing a TaskAttributes object
|
|
270
|
+
"""
|
|
271
|
+
parameters = {
|
|
272
|
+
"object_name": self.task_name,
|
|
273
|
+
"object_type": "task",
|
|
274
|
+
"attributes": attributes.json(),
|
|
275
|
+
}
|
|
276
|
+
with cursor() as cr:
|
|
277
|
+
cr.callproc(
|
|
278
|
+
"DBMS_CLOUD_AI_AGENT.SET_ATTRIBUTES",
|
|
279
|
+
keyword_parameters=parameters,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
def set_attribute(self, attribute_name: str, attribute_value: Any):
|
|
283
|
+
"""
|
|
284
|
+
Set a single AI Task attribute specified using name and value
|
|
285
|
+
|
|
286
|
+
:param str attribute_name: The name of the AI Task attribute
|
|
287
|
+
:param str attribute_value: The value of the AI Task attribute
|
|
288
|
+
|
|
289
|
+
"""
|
|
290
|
+
parameters = {
|
|
291
|
+
"object_name": self.task_name,
|
|
292
|
+
"object_type": "task",
|
|
293
|
+
"attribute_name": attribute_name,
|
|
294
|
+
"attribute_value": attribute_value,
|
|
295
|
+
}
|
|
296
|
+
with cursor() as cr:
|
|
297
|
+
cr.callproc(
|
|
298
|
+
"DBMS_CLOUD_AI_AGENT.SET_ATTRIBUTE",
|
|
299
|
+
keyword_parameters=parameters,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class AsyncTask(BaseTask):
|
|
304
|
+
"""
|
|
305
|
+
select_ai.agent.AsyncTask class lets you create, delete, enable, disable and
|
|
306
|
+
list AI Tasks asynchronously
|
|
307
|
+
|
|
308
|
+
:param str task_name: The name of the AI task
|
|
309
|
+
:param str description: Optional description of the AI task
|
|
310
|
+
:param select_ai.agent.TaskAttributes attributes: AI task attributes
|
|
311
|
+
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
@staticmethod
|
|
315
|
+
async def _get_attributes(task_name: str) -> TaskAttributes:
|
|
316
|
+
async with async_cursor() as cr:
|
|
317
|
+
await cr.execute(
|
|
318
|
+
GET_USER_AI_AGENT_TASK_ATTRIBUTES, task_name=task_name.upper()
|
|
319
|
+
)
|
|
320
|
+
attributes = await cr.fetchall()
|
|
321
|
+
if attributes:
|
|
322
|
+
post_processed_attributes = {}
|
|
323
|
+
for k, v in attributes:
|
|
324
|
+
if isinstance(v, oracledb.AsyncLOB):
|
|
325
|
+
post_processed_attributes[k] = await v.read()
|
|
326
|
+
else:
|
|
327
|
+
post_processed_attributes[k] = v
|
|
328
|
+
return TaskAttributes(**post_processed_attributes)
|
|
329
|
+
else:
|
|
330
|
+
raise AgentTaskNotFoundError(task_name=task_name)
|
|
331
|
+
|
|
332
|
+
@staticmethod
|
|
333
|
+
async def _get_description(task_name: str) -> Union[str, None]:
|
|
334
|
+
async with async_cursor() as cr:
|
|
335
|
+
await cr.execute(
|
|
336
|
+
GET_USER_AI_AGENT_TASK, task_name=task_name.upper()
|
|
337
|
+
)
|
|
338
|
+
task = await cr.fetchone()
|
|
339
|
+
if task:
|
|
340
|
+
if task[1] is not None:
|
|
341
|
+
return await task[1].read()
|
|
342
|
+
else:
|
|
343
|
+
return None
|
|
344
|
+
else:
|
|
345
|
+
raise AgentTaskNotFoundError(task_name)
|
|
346
|
+
|
|
347
|
+
async def create(
|
|
348
|
+
self, enabled: Optional[bool] = True, replace: Optional[bool] = False
|
|
349
|
+
):
|
|
350
|
+
"""
|
|
351
|
+
Create a task that a Select AI agent can include in its
|
|
352
|
+
reasoning process
|
|
353
|
+
|
|
354
|
+
:param bool enabled: Whether the AI Task should be enabled.
|
|
355
|
+
Default value is True.
|
|
356
|
+
|
|
357
|
+
:param bool replace: Whether the AI Task should be replaced.
|
|
358
|
+
Default value is False.
|
|
359
|
+
|
|
360
|
+
"""
|
|
361
|
+
if self.task_name is None:
|
|
362
|
+
raise AttributeError("Task must have a name")
|
|
363
|
+
if self.attributes is None:
|
|
364
|
+
raise AttributeError("Task must have attributes")
|
|
365
|
+
|
|
366
|
+
parameters = {
|
|
367
|
+
"task_name": self.task_name,
|
|
368
|
+
"attributes": self.attributes.json(),
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if self.description:
|
|
372
|
+
parameters["description"] = self.description
|
|
373
|
+
|
|
374
|
+
if not enabled:
|
|
375
|
+
parameters["status"] = "disabled"
|
|
376
|
+
|
|
377
|
+
async with async_cursor() as cr:
|
|
378
|
+
try:
|
|
379
|
+
await cr.callproc(
|
|
380
|
+
"DBMS_CLOUD_AI_AGENT.CREATE_TASK",
|
|
381
|
+
keyword_parameters=parameters,
|
|
382
|
+
)
|
|
383
|
+
except oracledb.Error as err:
|
|
384
|
+
(err_obj,) = err.args
|
|
385
|
+
if err_obj.code in (20051, 20052) and replace:
|
|
386
|
+
await self.delete(force=True)
|
|
387
|
+
await cr.callproc(
|
|
388
|
+
"DBMS_CLOUD_AI_AGENT.CREATE_TASK",
|
|
389
|
+
keyword_parameters=parameters,
|
|
390
|
+
)
|
|
391
|
+
else:
|
|
392
|
+
raise
|
|
393
|
+
|
|
394
|
+
async def delete(self, force: bool = False):
|
|
395
|
+
"""
|
|
396
|
+
Delete AI Task from the database
|
|
397
|
+
|
|
398
|
+
:param bool force: Force the deletion. Default value is False.
|
|
399
|
+
"""
|
|
400
|
+
async with async_cursor() as cr:
|
|
401
|
+
await cr.callproc(
|
|
402
|
+
"DBMS_CLOUD_AI_AGENT.DROP_TASK",
|
|
403
|
+
keyword_parameters={
|
|
404
|
+
"task_name": self.task_name,
|
|
405
|
+
"force": force,
|
|
406
|
+
},
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
async def disable(self):
|
|
410
|
+
"""
|
|
411
|
+
Disable AI Task
|
|
412
|
+
"""
|
|
413
|
+
async with async_cursor() as cr:
|
|
414
|
+
await cr.callproc(
|
|
415
|
+
"DBMS_CLOUD_AI_AGENT.DISABLE_TASK",
|
|
416
|
+
keyword_parameters={
|
|
417
|
+
"task_name": self.task_name,
|
|
418
|
+
},
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
async def enable(self):
|
|
422
|
+
"""
|
|
423
|
+
Enable AI Task
|
|
424
|
+
"""
|
|
425
|
+
async with async_cursor() as cr:
|
|
426
|
+
await cr.callproc(
|
|
427
|
+
"DBMS_CLOUD_AI_AGENT.ENABLE_TASK",
|
|
428
|
+
keyword_parameters={
|
|
429
|
+
"task_name": self.task_name,
|
|
430
|
+
},
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
@classmethod
|
|
434
|
+
async def list(
|
|
435
|
+
cls, task_name_pattern: Optional[str] = ".*"
|
|
436
|
+
) -> AsyncGenerator["AsyncTask", None]:
|
|
437
|
+
"""List AI Tasks
|
|
438
|
+
|
|
439
|
+
:param str task_name_pattern: Regular expressions can be used
|
|
440
|
+
to specify a pattern. Function REGEXP_LIKE is used to perform the
|
|
441
|
+
match. Default value is ".*" i.e. match all tasks.
|
|
442
|
+
|
|
443
|
+
:return: AsyncGenerator[Task]
|
|
444
|
+
"""
|
|
445
|
+
async with async_cursor() as cr:
|
|
446
|
+
await cr.execute(
|
|
447
|
+
LIST_USER_AI_AGENT_TASKS,
|
|
448
|
+
task_name_pattern=task_name_pattern,
|
|
449
|
+
)
|
|
450
|
+
rows = await cr.fetchall()
|
|
451
|
+
for row in rows:
|
|
452
|
+
task_name = row[0]
|
|
453
|
+
if row[1]:
|
|
454
|
+
description = await row[1].read() # Oracle.AsyncLOB
|
|
455
|
+
else:
|
|
456
|
+
description = None
|
|
457
|
+
attributes = await cls._get_attributes(task_name=task_name)
|
|
458
|
+
yield cls(
|
|
459
|
+
task_name=task_name,
|
|
460
|
+
description=description,
|
|
461
|
+
attributes=attributes,
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
@classmethod
|
|
465
|
+
async def fetch(cls, task_name: str) -> "AsyncTask":
|
|
466
|
+
"""
|
|
467
|
+
Fetch AI Task attributes from the Database and build a proxy object in
|
|
468
|
+
the Python layer
|
|
469
|
+
|
|
470
|
+
:param str task_name: The name of the AI Task
|
|
471
|
+
|
|
472
|
+
:return: select_ai.agent.Task
|
|
473
|
+
|
|
474
|
+
:raises select_ai.errors.AgentTaskNotFoundError:
|
|
475
|
+
If the AI Task is not found
|
|
476
|
+
"""
|
|
477
|
+
attributes = await cls._get_attributes(task_name=task_name)
|
|
478
|
+
description = await cls._get_description(task_name=task_name)
|
|
479
|
+
return cls(
|
|
480
|
+
task_name=task_name,
|
|
481
|
+
description=description,
|
|
482
|
+
attributes=attributes,
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
async def set_attributes(self, attributes: TaskAttributes):
|
|
486
|
+
"""
|
|
487
|
+
Set AI Task attributes
|
|
488
|
+
|
|
489
|
+
:param select_ai.agent.TaskAttributes attributes: Multiple attributes
|
|
490
|
+
can be specified by passing a TaskAttributes object
|
|
491
|
+
"""
|
|
492
|
+
parameters = {
|
|
493
|
+
"object_name": self.task_name,
|
|
494
|
+
"object_type": "task",
|
|
495
|
+
"attributes": attributes.json(),
|
|
496
|
+
}
|
|
497
|
+
async with async_cursor() as cr:
|
|
498
|
+
await cr.callproc(
|
|
499
|
+
"DBMS_CLOUD_AI_AGENT.SET_ATTRIBUTES",
|
|
500
|
+
keyword_parameters=parameters,
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
async def set_attribute(self, attribute_name: str, attribute_value: Any):
|
|
504
|
+
"""
|
|
505
|
+
Set a single AI Task attribute specified using name and value
|
|
506
|
+
|
|
507
|
+
:param str attribute_name: The name of the AI Task attribute
|
|
508
|
+
:param str attribute_value: The value of the AI Task attribute
|
|
509
|
+
|
|
510
|
+
"""
|
|
511
|
+
parameters = {
|
|
512
|
+
"object_name": self.task_name,
|
|
513
|
+
"object_type": "task",
|
|
514
|
+
"attribute_name": attribute_name,
|
|
515
|
+
"attribute_value": attribute_value,
|
|
516
|
+
}
|
|
517
|
+
async with async_cursor() as cr:
|
|
518
|
+
await cr.callproc(
|
|
519
|
+
"DBMS_CLOUD_AI_AGENT.SET_ATTRIBUTE",
|
|
520
|
+
keyword_parameters=parameters,
|
|
521
|
+
)
|