Skip to content

Commit e97c26c

Browse files
committed
OCI Agents updated
1 parent 9586b78 commit e97c26c

File tree

4 files changed

+612
-0
lines changed

4 files changed

+612
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
--
2+
-- NAME:
3+
-- provision_autonomous_database - Provision an Autonomous Database in OCI
4+
--
5+
-- DESCRIPTION:
6+
-- This function provisions an Autonomous Database (ADB-S) in a specified
7+
-- compartment within OCI. It takes workload type, compute and storage
8+
-- configurations, and database options as inputs, builds the request object,
9+
-- and calls DBMS_CLOUD_OCI_DB_DATABASE.CREATE_AUTONOMOUS_DATABASE to create
10+
-- the database. The result is returned as a structured JSON response (CLOB).
11+
--
12+
-- PARAMETERS:
13+
-- compartment_name (IN) - Name of the compartment where the ADB will be provisioned
14+
-- db_name (IN) - Database name (uppercase enforced)
15+
-- display_name (IN) - Optional display name for the database
16+
-- workload_type (IN) - Workload type: OLTP, ADW, JSON, or APEX
17+
-- ecpu_count (IN) - Number of ECPUs
18+
-- storage_tb (IN) - Storage size in TB
19+
-- region (IN) - Target OCI region for provisioning
20+
-- data_guard (IN) - Enable/Disable Data Guard ('ENABLED' / 'DISABLED')
21+
-- credential_name (IN) - Name of the stored credential (for DBMS_CLOUD)
22+
-- database_pwd (IN) - Admin password for the database
23+
-- is_auto_scaling_enabled (IN) - Flag for auto-scaling (1 = enabled, 0 = disabled)
24+
--
25+
-- RETURNS:
26+
-- CLOB containing JSON object with keys:
27+
-- - status : 'success' or 'error'
28+
-- - message : Status message
29+
-- - status_code : HTTP status code from OCI API (if success)
30+
-- - database_ocid : OCID of the provisioned database (if success)
31+
-- - database_name : Name of the provisioned database
32+
-- - workload_type : Workload type used for provisioning
33+
-- - ecpu_count : Number of ECPUs
34+
-- - region : Provisioned region
35+
-- - data_guard_enabled : 'ENABLED' or 'DISABLED'
36+
--
37+
-- EXAMPLE:
38+
-- SELECT provision_adbs_tool(
39+
-- compartment_name => 'COMP_DB',
40+
-- db_name => 'MYDB',
41+
-- display_name => 'My ADB',
42+
-- workload_type => 'OLTP',
43+
-- ecpu_count => 4,
44+
-- storage_tb => 2,
45+
-- region => 'us-ashburn-1',
46+
-- data_guard => 'DISABLED',
47+
-- credential_name => 'OCI_CRED',
48+
-- database_pwd => 'MySecurePwd#123',
49+
-- is_auto_scaling_enabled => 1
50+
-- )
51+
-- FROM dual;
52+
--
53+
-- NOTES:
54+
-- - Relies on get_compartment_ocid_by_name function to resolve the
55+
-- compartment OCID from its name.
56+
-- - Password must meet OCI’s complexity requirements.
57+
-- - Returns JSON error object if provisioning fails.
58+
-- - Uses DBMS_CLOUD_OCI to interact with OCI APIs.
59+
--
60+
61+
62+
CREATE OR REPLACE FUNCTION provision_autonomous_database(
63+
compartment_name IN VARCHAR2,
64+
db_name IN VARCHAR2,
65+
display_name IN VARCHAR2 default NULL,
66+
workload_type IN VARCHAR2,
67+
ecpu_count IN NUMBER,
68+
storage_tb IN NUMBER,
69+
region IN VARCHAR2,
70+
data_guard IN VARCHAR2,
71+
credential_name IN VARCHAR2,
72+
database_pwd IN VARCHAR2,
73+
is_auto_scaling_enabled IN NUMBER
74+
) RETURN CLOB
75+
IS
76+
in_details dbms_cloud_oci_database_create_autonomous_database_base_t :=
77+
dbms_cloud_oci_database_create_autonomous_database_base_t();
78+
resp dbms_cloud_oci_db_database_create_autonomous_database_response_t;
79+
result_json JSON_OBJECT_T := JSON_OBJECT_T();
80+
l_workload VARCHAR2(20);
81+
compartment_id VARCHAR2(256);
82+
l_compartment_name VARCHAR2(256);
83+
84+
BEGIN
85+
86+
87+
SELECT
88+
JSON_VALUE(
89+
get_compartment_ocid_by_name(credential_name, compartment_name),
90+
'$.compartment_ocid'
91+
) AS comp_ocid
92+
INTO compartment_id
93+
FROM dual;
94+
95+
-- Map workload types
96+
CASE UPPER(workload_type)
97+
WHEN 'OLTP' THEN l_workload := 'OLTP';
98+
WHEN 'ADW' THEN l_workload := 'DW';
99+
WHEN 'JSON' THEN l_workload := 'JSON';
100+
WHEN 'APEX' THEN l_workload := 'APEX';
101+
ELSE l_workload := 'OLTP';
102+
END CASE;
103+
104+
-- Setup the database details
105+
in_details.compartment_id := compartment_id;
106+
in_details.db_name := UPPER(db_name);
107+
in_details.compute_model := 'ECPU';
108+
in_details.compute_count := ecpu_count;
109+
in_details.data_storage_size_in_t_bs := storage_tb;
110+
in_details.admin_password := database_pwd; -- In production, use secure password generation
111+
in_details.db_workload := l_workload;
112+
in_details.display_name := display_name;
113+
in_details.is_auto_scaling_enabled := is_auto_scaling_enabled;
114+
115+
-- Enable Data Guard if requested
116+
IF UPPER(data_guard) = 'ENABLED' THEN
117+
in_details.is_data_guard_enabled := 0;
118+
result_json.put('data_guard_enabled', 'ENABLED');
119+
ELSE
120+
in_details.is_data_guard_enabled := 0;
121+
result_json.put('data_guard_enabled', 'DISABLED');
122+
END IF;
123+
124+
-- Create the database
125+
BEGIN
126+
resp := DBMS_CLOUD_OCI_DB_DATABASE.CREATE_AUTONOMOUS_DATABASE(
127+
create_autonomous_database_details => in_details,
128+
credential_name => credential_name,
129+
region => region
130+
);
131+
132+
-- Build success response
133+
result_json.put('status', 'success');
134+
result_json.put('message', 'Autonomous Database provisioning initiated successfully');
135+
result_json.put('status_code', resp.status_code);
136+
result_json.put('database_ocid', resp.response_body.id);
137+
result_json.put('database_name', db_name);
138+
result_json.put('workload_type', l_workload);
139+
result_json.put('ecpu_count', ecpu_count);
140+
result_json.put('region', region);
141+
142+
143+
EXCEPTION
144+
WHEN OTHERS THEN
145+
result_json.put('status', 'error');
146+
result_json.put('message', 'Failed to provision Autonomous Database: ' || SQLERRM);
147+
END;
148+
149+
RETURN result_json.to_clob();
150+
151+
END provision_autonomous_database;
152+
/
153+
154+
--Drop tool if exists
155+
156+
DECLARE
157+
l_tool_count NUMBER;
158+
BEGIN
159+
-- Check if the tool exists
160+
SELECT COUNT(*)
161+
INTO l_tool_count
162+
FROM USER_AI_AGENT_TOOLS
163+
WHERE TOOL_NAME = 'ADBS_PROVISIONING_TOOL';
164+
165+
-- Drop only if it exists
166+
IF l_tool_count > 0 THEN
167+
DBMS_CLOUD_AI_AGENT.DROP_TOOL('ADBS_PROVISIONING_TOOL');
168+
END IF;
169+
END;
170+
/
171+
172+
BEGIN
173+
DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
174+
tool_name => 'ADBS_PROVISIONING_TOOL',
175+
attributes => '{"instruction": "This tool provisions an Oracle Autonomous Database.'||
176+
'Use LIST_SUBSCRIBED_REGIONS_TOOL to check all available regions that the user subscribes to. ' ||
177+
'You need confirm which region to use with the user if there are multiple regions ' ||
178+
'If there is only one region, you can use it by default. ' ||
179+
'Use LIST_COMPARTMENTS_TOOL and provide the list of compartments as bullet list.You need confirm which compartment to use with the user.'||
180+
'Use ADBS_PROVISIONING_TOOL to provision database only after you have gathered ALL required information. ' ||
181+
'Get all the inputs at once ' ||
182+
'Must get final confirmation by summarizing all choices before provisioning. ",
183+
"function" : "provision_autonomous_database"}',
184+
description => 'Tool for provisioning Oracle Autonomous Databases'
185+
);
186+
END;
187+
/
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
--
2+
-- NAME:
3+
-- get_compartment_ocid - Retrieve the OCID of a given compartment
4+
--
5+
-- DESCRIPTION:
6+
-- This function retrieves the OCID (Oracle Cloud Identifier) for a specific
7+
-- compartment by name within a tenancy. It internally calls the
8+
-- list_compartments function to fetch all available compartments, then
9+
-- searches for the compartment with the given name. The result is returned
10+
-- as a structured JSON object (CLOB).
11+
--
12+
-- PARAMETERS:
13+
-- credential_name (IN) - Name of the stored credential (for DBMS_CLOUD)
14+
-- compartment_name (IN) - Name of the compartment to search for
15+
--
16+
-- RETURNS:
17+
-- CLOB containing JSON object with keys:
18+
-- - status : 'success' or 'error'
19+
-- - compartment_name : Name of the matched compartment (if success)
20+
-- - compartment_ocid : OCID of the matched compartment (if success)
21+
-- - message : Error message if compartment not found or request fails
22+
--
23+
-- EXAMPLE:
24+
-- SELECT get_compartment_ocid('OCI_CRED', 'COMP_DB')
25+
-- FROM dual;
26+
--
27+
-- NOTES:
28+
-- - Relies on the list_compartments function to fetch compartment details.
29+
-- - Returns an error JSON if the compartment name is not found or if an
30+
-- unexpected error occurs.
31+
-- - Uses DBMS_CLOUD.send_request and JSON parsing APIs.
32+
--
33+
34+
35+
create or replace FUNCTION get_compartment_ocid(
36+
credential_name IN VARCHAR2,
37+
compartment_name IN VARCHAR2
38+
) RETURN CLOB
39+
IS
40+
l_comp_json_clob CLOB;
41+
l_result_json JSON_OBJECT_T := JSON_OBJECT_T();
42+
l_compartments JSON_ARRAY_T;
43+
l_comp_obj JSON_OBJECT_T;
44+
l_name VARCHAR2(200);
45+
l_ocid VARCHAR2(200);
46+
found BOOLEAN := FALSE;
47+
l_compartment_name VARCHAR2(256);
48+
BEGIN
49+
50+
-- Call existing list_compartments function
51+
l_comp_json_clob := list_compartments(credential_name);
52+
53+
-- Parse returned JSON object
54+
l_result_json := JSON_OBJECT_T.parse(l_comp_json_clob);
55+
56+
IF l_result_json.get('status').to_string() = '"success"' THEN
57+
-- Extract compartments array
58+
l_compartments := l_result_json.get_Array('compartments');
59+
60+
-- Loop through compartments to find matching name
61+
FOR i IN 0 .. l_compartments.get_size() - 1 LOOP
62+
l_comp_obj := JSON_OBJECT_T(l_compartments.get(i));
63+
l_name := l_comp_obj.get_string('name');
64+
65+
IF l_name = compartment_name THEN
66+
l_ocid := l_comp_obj.get_string('id');
67+
found := TRUE;
68+
EXIT;
69+
END IF;
70+
END LOOP;
71+
72+
IF found THEN
73+
l_result_json := JSON_OBJECT_T();
74+
l_result_json.put('status', 'success');
75+
l_result_json.put('compartment_name', compartment_name);
76+
l_result_json.put('compartment_ocid', l_ocid);
77+
ELSE
78+
l_result_json := JSON_OBJECT_T();
79+
l_result_json.put('status', 'error');
80+
l_result_json.put('message', 'Compartment name "' || compartment_name || '" not found');
81+
END IF;
82+
83+
ELSE
84+
-- Forward error from list_compartments function
85+
RETURN l_comp_json_clob;
86+
END IF;
87+
88+
RETURN l_result_json.to_clob();
89+
90+
EXCEPTION
91+
WHEN OTHERS THEN
92+
l_result_json := JSON_OBJECT_T();
93+
l_result_json.put('status', 'error');
94+
l_result_json.put('message', 'Unexpected error: ' || SQLERRM);
95+
RETURN l_result_json.to_clob();
96+
END get_compartment_ocid;
97+
/
98+
99+
--Drop tool if exists
100+
101+
DECLARE
102+
l_tool_count NUMBER;
103+
BEGIN
104+
-- Check if the tool exists
105+
SELECT COUNT(*)
106+
INTO l_tool_count
107+
FROM USER_AI_AGENT_TOOLS
108+
WHERE TOOL_NAME = 'GET_COMPARTMENT_OCID_TOOL';
109+
110+
-- Drop only if it exists
111+
IF l_tool_count > 0 THEN
112+
DBMS_CLOUD_AI_AGENT.DROP_TOOL('GET_COMPARTMENT_OCID_TOOL');
113+
END IF;
114+
END;
115+
/
116+
117+
--Create tool
118+
119+
BEGIN
120+
DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
121+
tool_name => 'GET_COMPARTMENT_OCID_TOOL',
122+
attributes => '{
123+
"instruction": "This tool accepts OCI credentials and a compartment name, and returns the OCID of that compartment.",
124+
"function": "get_compartment_ocid"
125+
}',
126+
description => 'Tool to get compartment OCID by name'
127+
);
128+
END;
129+
/

0 commit comments

Comments
 (0)