oci 2.151.0__py3-none-any.whl → 2.152.1__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.
Files changed (430) hide show
  1. oci/__init__.py +2 -2
  2. oci/access_governance_cp/access_governance_cp_client.py +8 -8
  3. oci/addons/__init__.py +20 -0
  4. oci/addons/adk/__init__.py +13 -0
  5. oci/addons/adk/agent.py +852 -0
  6. oci/addons/adk/agent_client.py +682 -0
  7. oci/addons/adk/agent_error.py +36 -0
  8. oci/addons/adk/auth/__init__.py +5 -0
  9. oci/addons/adk/auth/auth_provider.py +28 -0
  10. oci/addons/adk/auth/factory.py +78 -0
  11. oci/addons/adk/auth/oci/__init__.py +5 -0
  12. oci/addons/adk/auth/oci/instance_principal.py +53 -0
  13. oci/addons/adk/auth/oci/resource_principal.py +53 -0
  14. oci/addons/adk/auth/oci/session.py +91 -0
  15. oci/addons/adk/auth/oci/user_principal.py +64 -0
  16. oci/addons/adk/constants.py +17 -0
  17. oci/addons/adk/logger.py +163 -0
  18. oci/addons/adk/run/__init__.py +5 -0
  19. oci/addons/adk/run/response.py +56 -0
  20. oci/addons/adk/run/types.py +32 -0
  21. oci/addons/adk/tool/__init__.py +13 -0
  22. oci/addons/adk/tool/function_tool.py +334 -0
  23. oci/addons/adk/tool/prebuilt/__init__.py +8 -0
  24. oci/addons/adk/tool/prebuilt/agentic_rag_tool.py +49 -0
  25. oci/addons/adk/tool/prebuilt/calculator_toolkit.py +104 -0
  26. oci/addons/adk/tool/tool.py +37 -0
  27. oci/addons/adk/tool/toolkit.py +189 -0
  28. oci/addons/adk/tool/utils.py +120 -0
  29. oci/addons/adk/util.py +325 -0
  30. oci/adm/application_dependency_management_client.py +36 -36
  31. oci/ai_anomaly_detection/anomaly_detection_client.py +36 -36
  32. oci/ai_document/ai_service_document_client.py +26 -26
  33. oci/ai_language/ai_service_language_client.py +44 -44
  34. oci/ai_speech/ai_service_speech_client.py +19 -19
  35. oci/ai_vision/ai_service_vision_client.py +28 -28
  36. oci/analytics/analytics_client.py +24 -24
  37. oci/announcements_service/announcement_client.py +5 -5
  38. oci/announcements_service/announcement_subscription_client.py +9 -9
  39. oci/announcements_service/announcements_preferences_client.py +4 -4
  40. oci/announcements_service/service_client.py +1 -1
  41. oci/apigateway/api_gateway_client.py +21 -21
  42. oci/apigateway/deployment_client.py +6 -6
  43. oci/apigateway/gateway_client.py +6 -6
  44. oci/apigateway/subscribers_client.py +6 -6
  45. oci/apigateway/usage_plans_client.py +6 -6
  46. oci/apigateway/work_requests_client.py +5 -5
  47. oci/apm_config/config_client.py +12 -12
  48. oci/apm_control_plane/apm_domain_client.py +14 -14
  49. oci/apm_synthetics/apm_synthetic_client.py +28 -28
  50. oci/apm_traces/attributes_client.py +8 -8
  51. oci/apm_traces/query_client.py +2 -2
  52. oci/apm_traces/trace_client.py +4 -4
  53. oci/appmgmt_control/appmgmt_control_client.py +8 -8
  54. oci/artifacts/artifacts_client.py +32 -32
  55. oci/audit/audit_client.py +3 -3
  56. oci/autoscaling/auto_scaling_client.py +11 -11
  57. oci/bastion/bastion_client.py +15 -15
  58. oci/bds/bds_client.py +84 -84
  59. oci/blockchain/blockchain_platform_client.py +27 -27
  60. oci/budget/budget_client.py +10 -10
  61. oci/capacity_management/capacity_management_client.py +32 -32
  62. oci/certificates/certificates_client.py +5 -5
  63. oci/certificates_management/certificates_management_client.py +32 -32
  64. oci/cims/incident_client.py +6 -6
  65. oci/cloud_bridge/common_client.py +5 -5
  66. oci/cloud_bridge/discovery_client.py +15 -15
  67. oci/cloud_bridge/inventory_client.py +16 -16
  68. oci/cloud_bridge/ocb_agent_svc_client.py +23 -23
  69. oci/cloud_guard/cloud_guard_client.py +155 -155
  70. oci/cloud_migrations/migration_client.py +43 -43
  71. oci/cluster_placement_groups/cluster_placement_groups_cp_client.py +13 -13
  72. oci/compute_cloud_at_customer/compute_cloud_at_customer_client.py +12 -12
  73. oci/compute_instance_agent/compute_instance_agent_client.py +6 -6
  74. oci/compute_instance_agent/plugin_client.py +2 -2
  75. oci/compute_instance_agent/pluginconfig_client.py +1 -1
  76. oci/container_engine/container_engine_client.py +46 -46
  77. oci/container_instances/container_instance_client.py +18 -18
  78. oci/core/blockstorage_client.py +60 -60
  79. oci/core/compute_client.py +117 -117
  80. oci/core/compute_management_client.py +32 -32
  81. oci/core/virtual_network_client.py +258 -258
  82. oci/dashboard_service/dashboard_client.py +6 -6
  83. oci/dashboard_service/dashboard_group_client.py +6 -6
  84. oci/data_catalog/data_catalog_client.py +149 -149
  85. oci/data_flow/data_flow_client.py +45 -45
  86. oci/data_integration/data_integration_client.py +163 -163
  87. oci/data_labeling_service/data_labeling_management_client.py +17 -17
  88. oci/data_labeling_service_dataplane/data_labeling_client.py +15 -15
  89. oci/data_safe/data_safe_client.py +317 -317
  90. oci/data_science/data_science_client.py +145 -145
  91. oci/database/database_client.py +745 -469
  92. oci/database/models/__init__.py +2 -0
  93. oci/database/models/autonomous_db_version_summary.py +31 -0
  94. oci/database/models/backup.py +4 -2
  95. oci/database/models/backup_summary.py +4 -2
  96. oci/database/models/create_external_backup_job_details.py +4 -4
  97. oci/database/models/db_system.py +4 -2
  98. oci/database/models/db_system_summary.py +4 -2
  99. oci/database/models/db_system_upgrade_summary.py +152 -0
  100. oci/database/models/external_container_database.py +4 -2
  101. oci/database/models/external_container_database_summary.py +4 -2
  102. oci/database/models/external_database_base.py +4 -2
  103. oci/database/models/external_non_container_database.py +4 -2
  104. oci/database/models/external_non_container_database_summary.py +4 -2
  105. oci/database/models/external_pluggable_database.py +4 -2
  106. oci/database/models/external_pluggable_database_summary.py +4 -2
  107. oci/database_management/db_management_client.py +356 -230
  108. oci/database_management/db_management_client_composite_operations.py +44 -0
  109. oci/database_management/diagnosability_client.py +4 -4
  110. oci/database_management/managed_my_sql_databases_client.py +7 -247
  111. oci/database_management/models/__init__.py +0 -4
  112. oci/database_management/models/database_diagnostics_and_management_feature_details.py +35 -4
  113. oci/database_management/models/disable_database_management_feature_details.py +33 -2
  114. oci/database_management/models/disable_external_container_database_management_feature_details.py +33 -2
  115. oci/database_management/models/discovered_external_database.py +64 -2
  116. oci/database_management/models/exadata_infrastructure_lifecycle_state_values.py +40 -36
  117. oci/database_management/models/external_database_diagnostics_and_management_feature_details.py +64 -2
  118. oci/database_management/models/managed_database.py +2 -4
  119. oci/database_management/models/managed_database_summary.py +2 -4
  120. oci/database_management/models/modify_database_management_feature_details.py +1 -1
  121. oci/database_management/perfhub_client.py +1 -1
  122. oci/database_management/sql_tuning_client.py +17 -17
  123. oci/database_migration/database_migration_client.py +42 -42
  124. oci/database_tools/database_tools_client.py +23 -23
  125. oci/dblm/db_life_cycle_management_client.py +14 -14
  126. oci/delegate_access_control/delegate_access_control_client.py +26 -26
  127. oci/delegate_access_control/work_request_client.py +4 -4
  128. oci/demand_signal/occ_demand_signal_client.py +7 -7
  129. oci/desktops/desktop_service_client.py +21 -21
  130. oci/devops/devops_client.py +141 -141
  131. oci/disaster_recovery/disaster_recovery_client.py +31 -31
  132. oci/distributed_database/__init__.py +20 -0
  133. oci/distributed_database/distributed_autonomous_db_service_client.py +2315 -0
  134. oci/distributed_database/distributed_autonomous_db_service_client_composite_operations.py +605 -0
  135. oci/distributed_database/distributed_db_private_endpoint_service_client.py +944 -0
  136. oci/distributed_database/distributed_db_private_endpoint_service_client_composite_operations.py +238 -0
  137. oci/distributed_database/distributed_db_service_client.py +2435 -0
  138. oci/distributed_database/distributed_db_service_client_composite_operations.py +647 -0
  139. oci/distributed_database/distributed_db_work_request_service_client.py +654 -0
  140. oci/distributed_database/distributed_db_work_request_service_client_composite_operations.py +26 -0
  141. oci/distributed_database/models/__init__.py +158 -0
  142. oci/distributed_database/models/add_distributed_autonomous_database_gds_control_node_details.py +105 -0
  143. oci/distributed_database/models/add_distributed_database_gds_control_node_details.py +105 -0
  144. oci/distributed_database/models/catalog_peer_with_dedicated_infra.py +331 -0
  145. oci/distributed_database/models/catalog_peer_with_exadb_xs.py +331 -0
  146. oci/distributed_database/models/change_distributed_autonomous_database_compartment_details.py +74 -0
  147. oci/distributed_database/models/change_distributed_database_compartment_details.py +74 -0
  148. oci/distributed_database/models/change_distributed_database_private_endpoint_compartment_details.py +74 -0
  149. oci/distributed_database/models/change_distributed_db_backup_config_details.py +66 -0
  150. oci/distributed_database/models/configure_distributed_autonomous_database_gsms_details.py +103 -0
  151. oci/distributed_database/models/configure_distributed_database_gsms_details.py +103 -0
  152. oci/distributed_database/models/create_distributed_autonomous_database_catalog_details.py +101 -0
  153. oci/distributed_database/models/create_distributed_autonomous_database_catalog_with_dedicated_infra_details.py +342 -0
  154. oci/distributed_database/models/create_distributed_autonomous_database_details.py +799 -0
  155. oci/distributed_database/models/create_distributed_autonomous_database_shard_details.py +101 -0
  156. oci/distributed_database/models/create_distributed_autonomous_database_shard_with_dedicated_infra_details.py +377 -0
  157. oci/distributed_database/models/create_distributed_database_catalog_details.py +99 -0
  158. oci/distributed_database/models/create_distributed_database_catalog_with_exadb_xs_details.py +282 -0
  159. oci/distributed_database/models/create_distributed_database_details.py +810 -0
  160. oci/distributed_database/models/create_distributed_database_private_endpoint_details.py +260 -0
  161. oci/distributed_database/models/create_distributed_database_shard_details.py +99 -0
  162. oci/distributed_database/models/create_distributed_database_shard_with_exadb_xs_details.py +282 -0
  163. oci/distributed_database/models/distributed_autonomous_database.py +1143 -0
  164. oci/distributed_database/models/distributed_autonomous_database_associated_with_private_endpoint.py +105 -0
  165. oci/distributed_database/models/distributed_autonomous_database_catalog.py +194 -0
  166. oci/distributed_database/models/distributed_autonomous_database_catalog_with_dedicated_infra.py +559 -0
  167. oci/distributed_database/models/distributed_autonomous_database_collection.py +70 -0
  168. oci/distributed_database/models/distributed_autonomous_database_connection_string.py +70 -0
  169. oci/distributed_database/models/distributed_autonomous_database_gsm.py +385 -0
  170. oci/distributed_database/models/distributed_autonomous_database_gsm_image.py +105 -0
  171. oci/distributed_database/models/distributed_autonomous_database_shard.py +194 -0
  172. oci/distributed_database/models/distributed_autonomous_database_shard_with_dedicated_infra.py +592 -0
  173. oci/distributed_database/models/distributed_autonomous_database_summary.py +935 -0
  174. oci/distributed_database/models/distributed_autonomous_db_metadata.py +70 -0
  175. oci/distributed_database/models/distributed_database.py +1154 -0
  176. oci/distributed_database/models/distributed_database_associated_with_private_endpoint.py +105 -0
  177. oci/distributed_database/models/distributed_database_catalog.py +192 -0
  178. oci/distributed_database/models/distributed_database_catalog_with_exadb_xs.py +466 -0
  179. oci/distributed_database/models/distributed_database_collection.py +70 -0
  180. oci/distributed_database/models/distributed_database_gsm.py +385 -0
  181. oci/distributed_database/models/distributed_database_private_endpoint.py +639 -0
  182. oci/distributed_database/models/distributed_database_private_endpoint_collection.py +70 -0
  183. oci/distributed_database/models/distributed_database_private_endpoint_summary.py +479 -0
  184. oci/distributed_database/models/distributed_database_shard.py +192 -0
  185. oci/distributed_database/models/distributed_database_shard_with_exadb_xs.py +499 -0
  186. oci/distributed_database/models/distributed_database_summary.py +904 -0
  187. oci/distributed_database/models/distributed_db_backup_config.py +536 -0
  188. oci/distributed_database/models/distributed_db_backup_destination.py +362 -0
  189. oci/distributed_database/models/distributed_db_connection_string.py +70 -0
  190. oci/distributed_database/models/distributed_db_gsm_image.py +105 -0
  191. oci/distributed_database/models/distributed_db_metadata.py +70 -0
  192. oci/distributed_database/models/generate_distributed_autonomous_database_wallet_details.py +70 -0
  193. oci/distributed_database/models/generate_distributed_database_wallet_details.py +70 -0
  194. oci/distributed_database/models/patch_distributed_autonomous_database_details.py +73 -0
  195. oci/distributed_database/models/patch_distributed_database_details.py +73 -0
  196. oci/distributed_database/models/patch_insert_instruction.py +87 -0
  197. oci/distributed_database/models/patch_instruction.py +154 -0
  198. oci/distributed_database/models/patch_merge_instruction.py +95 -0
  199. oci/distributed_database/models/patch_remove_instruction.py +57 -0
  200. oci/distributed_database/models/shard_peer_with_dedicated_infra.py +331 -0
  201. oci/distributed_database/models/shard_peer_with_exadb_xs.py +331 -0
  202. oci/distributed_database/models/update_distributed_autonomous_database_details.py +136 -0
  203. oci/distributed_database/models/update_distributed_database_details.py +136 -0
  204. oci/distributed_database/models/update_distributed_database_private_endpoint_details.py +198 -0
  205. oci/distributed_database/models/upload_distributed_autonomous_database_signed_certificate_and_generate_wallet_details.py +71 -0
  206. oci/distributed_database/models/upload_distributed_database_signed_certificate_and_generate_wallet_details.py +71 -0
  207. oci/distributed_database/models/work_request.py +516 -0
  208. oci/distributed_database/models/work_request_error.py +134 -0
  209. oci/distributed_database/models/work_request_error_collection.py +70 -0
  210. oci/distributed_database/models/work_request_log_entry.py +101 -0
  211. oci/distributed_database/models/work_request_log_entry_collection.py +70 -0
  212. oci/distributed_database/models/work_request_resource.py +232 -0
  213. oci/distributed_database/models/work_request_summary.py +516 -0
  214. oci/distributed_database/models/work_request_summary_collection.py +70 -0
  215. oci/dns/dns_client.py +54 -54
  216. oci/dts/appliance_export_job_client.py +6 -6
  217. oci/dts/shipping_vendors_client.py +1 -1
  218. oci/dts/transfer_appliance_client.py +8 -8
  219. oci/dts/transfer_appliance_entitlement_client.py +3 -3
  220. oci/dts/transfer_device_client.py +5 -5
  221. oci/dts/transfer_job_client.py +6 -6
  222. oci/dts/transfer_package_client.py +7 -7
  223. oci/em_warehouse/em_warehouse_client.py +13 -13
  224. oci/email/email_client.py +31 -31
  225. oci/email_data_plane/email_dp_client.py +1 -1
  226. oci/events/events_client.py +6 -6
  227. oci/file_storage/file_storage_client.py +74 -74
  228. oci/fleet_apps_management/fleet_apps_management_admin_client.py +27 -27
  229. oci/fleet_apps_management/fleet_apps_management_catalog_client.py +7 -7
  230. oci/fleet_apps_management/fleet_apps_management_client.py +32 -32
  231. oci/fleet_apps_management/fleet_apps_management_maintenance_window_client.py +5 -5
  232. oci/fleet_apps_management/fleet_apps_management_operations_client.py +29 -29
  233. oci/fleet_apps_management/fleet_apps_management_provision_client.py +6 -6
  234. oci/fleet_apps_management/fleet_apps_management_runbooks_client.py +19 -19
  235. oci/fleet_apps_management/fleet_apps_management_work_request_client.py +4 -4
  236. oci/fleet_software_update/fleet_software_update_client.py +46 -46
  237. oci/functions/functions_invoke_client.py +1 -1
  238. oci/functions/functions_management_client.py +16 -16
  239. oci/fusion_apps/fusion_applications_client.py +41 -41
  240. oci/generative_ai/generative_ai_client.py +22 -22
  241. oci/generative_ai/models/create_dedicated_ai_cluster_details.py +4 -0
  242. oci/generative_ai/models/dedicated_ai_cluster.py +11 -3
  243. oci/generative_ai_agent/generative_ai_agent_client.py +38 -38
  244. oci/generative_ai_agent_runtime/generative_ai_agent_runtime_client.py +6 -6
  245. oci/generative_ai_inference/generative_ai_inference_client.py +6 -6
  246. oci/generic_artifacts_content/generic_artifacts_content_client.py +3 -3
  247. oci/globally_distributed_database/sharded_database_service_client.py +58 -58
  248. oci/golden_gate/golden_gate_client.py +89 -89
  249. oci/governance_rules_control_plane/governance_rule_client.py +15 -15
  250. oci/governance_rules_control_plane/work_request_client.py +5 -5
  251. oci/healthchecks/health_checks_client.py +17 -17
  252. oci/identity/identity_client.py +145 -145
  253. oci/identity_data_plane/dataplane_client.py +2 -2
  254. oci/identity_domains/identity_domains_client.py +311 -311
  255. oci/integration/integration_instance_client.py +19 -19
  256. oci/jms/java_management_service_client.py +79 -79
  257. oci/jms_java_downloads/java_download_client.py +25 -25
  258. oci/key_management/ekm_client.py +5 -5
  259. oci/key_management/kms_crypto_client.py +6 -6
  260. oci/key_management/kms_hsm_cluster_client.py +12 -12
  261. oci/key_management/kms_management_client.py +21 -21
  262. oci/key_management/kms_vault_client.py +14 -14
  263. oci/license_manager/license_manager_client.py +18 -18
  264. oci/limits/limits_client.py +4 -4
  265. oci/limits/quotas_client.py +7 -7
  266. oci/load_balancer/load_balancer_client.py +61 -61
  267. oci/lockbox/lockbox_client.py +24 -24
  268. oci/log_analytics/log_analytics_client.py +200 -200
  269. oci/logging/logging_management_client.py +30 -30
  270. oci/loggingingestion/logging_client.py +1 -1
  271. oci/loggingsearch/log_search_client.py +1 -1
  272. oci/lustre_file_storage/lustre_file_storage_client.py +11 -11
  273. oci/management_agent/management_agent_client.py +28 -28
  274. oci/management_dashboard/dashx_apis_client.py +14 -14
  275. oci/marketplace/account_client.py +2 -2
  276. oci/marketplace/marketplace_client.py +30 -30
  277. oci/marketplace_private_offer/attachment_client.py +5 -5
  278. oci/marketplace_private_offer/offer_client.py +6 -6
  279. oci/marketplace_publisher/attachment_client.py +5 -5
  280. oci/marketplace_publisher/marketplace_publisher_client.py +71 -71
  281. oci/marketplace_publisher/offer_client.py +6 -6
  282. oci/media_services/media_services_client.py +60 -60
  283. oci/media_services/media_stream_client.py +2 -2
  284. oci/mngdmac/mac_device_client.py +3 -3
  285. oci/mngdmac/mac_order_client.py +11 -11
  286. oci/model_deployment/__init__.py +14 -0
  287. oci/model_deployment/model_deployment_client.py +331 -0
  288. oci/model_deployment/model_deployment_client_composite_operations.py +26 -0
  289. oci/model_deployment/models/__init__.py +14 -0
  290. oci/model_deployment/models/inference_result.py +70 -0
  291. oci/monitoring/monitoring_client.py +18 -18
  292. oci/mysql/channels_client.py +7 -7
  293. oci/mysql/db_backups_client.py +7 -7
  294. oci/mysql/db_system_client.py +17 -17
  295. oci/mysql/models/create_db_system_details.py +31 -0
  296. oci/mysql/models/db_system.py +31 -0
  297. oci/mysql/models/db_system_snapshot.py +31 -0
  298. oci/mysql/models/replica.py +31 -0
  299. oci/mysql/models/replica_overrides.py +33 -2
  300. oci/mysql/models/replica_summary.py +31 -0
  301. oci/mysql/models/update_db_system_details.py +31 -0
  302. oci/mysql/mysqlaas_client.py +7 -7
  303. oci/mysql/replicas_client.py +5 -5
  304. oci/mysql/work_requests_client.py +4 -4
  305. oci/network_firewall/network_firewall_client.py +86 -86
  306. oci/network_load_balancer/network_load_balancer_client.py +35 -35
  307. oci/nosql/nosql_client.py +24 -24
  308. oci/object_storage/object_storage_client.py +55 -55
  309. oci/oce/oce_instance_client.py +10 -10
  310. oci/oci_control_center/occ_metrics_client.py +3 -3
  311. oci/ocvp/cluster_client.py +5 -5
  312. oci/ocvp/esxi_host_client.py +8 -8
  313. oci/ocvp/sddc_client.py +14 -14
  314. oci/ocvp/work_request_client.py +4 -4
  315. oci/oda/management_client.py +59 -59
  316. oci/oda/oda_client.py +17 -17
  317. oci/oda/odapackage_client.py +7 -7
  318. oci/onesubscription/billing_schedule_client.py +1 -1
  319. oci/onesubscription/commitment_client.py +2 -2
  320. oci/onesubscription/computed_usage_client.py +3 -3
  321. oci/onesubscription/invoice_summary_client.py +2 -2
  322. oci/onesubscription/organization_subscription_client.py +1 -1
  323. oci/onesubscription/ratecard_client.py +1 -1
  324. oci/onesubscription/subscribed_service_client.py +2 -2
  325. oci/onesubscription/subscription_client.py +1 -1
  326. oci/ons/notification_control_plane_client.py +6 -6
  327. oci/ons/notification_data_plane_client.py +10 -10
  328. oci/opa/opa_instance_client.py +13 -13
  329. oci/opensearch/models/__init__.py +2 -0
  330. oci/opensearch/models/create_opensearch_cluster_details.py +291 -0
  331. oci/opensearch/models/create_opensearch_cluster_pipeline_details.py +31 -0
  332. oci/opensearch/models/opensearch_cluster.py +291 -0
  333. oci/opensearch/models/opensearch_cluster_pipeline.py +31 -0
  334. oci/opensearch/models/opensearch_cluster_pipeline_summary.py +31 -0
  335. oci/opensearch/models/resize_opensearch_cluster_horizontal_details.py +31 -0
  336. oci/opensearch/models/resize_opensearch_cluster_vertical_details.py +217 -0
  337. oci/opensearch/models/shapes_details.py +70 -0
  338. oci/opensearch/models/update_cluster_specs_details.py +186 -0
  339. oci/opensearch/models/update_opensearch_cluster_pipeline_details.py +31 -0
  340. oci/opensearch/opensearch_cluster_backup_client.py +4 -4
  341. oci/opensearch/opensearch_cluster_client.py +87 -16
  342. oci/opensearch/opensearch_cluster_pipeline_client.py +5 -5
  343. oci/operator_access_control/access_requests_client.py +10 -10
  344. oci/operator_access_control/operator_actions_client.py +2 -2
  345. oci/operator_access_control/operator_control_assignment_client.py +8 -8
  346. oci/operator_access_control/operator_control_client.py +6 -6
  347. oci/opsi/operations_insights_client.py +181 -181
  348. oci/optimizer/optimizer_client.py +26 -26
  349. oci/os_management/event_client.py +8 -8
  350. oci/os_management/os_management_client.py +69 -69
  351. oci/os_management_hub/event_client.py +8 -8
  352. oci/os_management_hub/lifecycle_environment_client.py +13 -13
  353. oci/os_management_hub/managed_instance_client.py +33 -33
  354. oci/os_management_hub/managed_instance_group_client.py +26 -26
  355. oci/os_management_hub/management_station_client.py +10 -10
  356. oci/os_management_hub/onboarding_client.py +13 -13
  357. oci/os_management_hub/reporting_managed_instance_client.py +3 -3
  358. oci/os_management_hub/scheduled_job_client.py +7 -7
  359. oci/os_management_hub/software_source_client.py +33 -33
  360. oci/os_management_hub/work_request_client.py +5 -5
  361. oci/osp_gateway/address_rule_service_client.py +1 -1
  362. oci/osp_gateway/address_service_client.py +2 -2
  363. oci/osp_gateway/invoice_service_client.py +5 -5
  364. oci/osp_gateway/subscription_service_client.py +5 -5
  365. oci/osub_billing_schedule/billing_schedule_client.py +1 -1
  366. oci/osub_organization_subscription/organization_subscription_client.py +1 -1
  367. oci/osub_subscription/commitment_client.py +2 -2
  368. oci/osub_subscription/ratecard_client.py +1 -1
  369. oci/osub_subscription/subscription_client.py +1 -1
  370. oci/osub_usage/computed_usage_client.py +3 -3
  371. oci/psql/postgresql_client.py +34 -34
  372. oci/queue/queue_admin_client.py +11 -11
  373. oci/queue/queue_client.py +8 -8
  374. oci/recovery/database_recovery_client.py +26 -26
  375. oci/redis/redis_cluster_client.py +12 -12
  376. oci/resource_manager/resource_manager_client.py +52 -52
  377. oci/resource_scheduler/schedule_client.py +14 -14
  378. oci/resource_search/resource_search_client.py +3 -3
  379. oci/rover/rover_bundle_client.py +8 -8
  380. oci/rover/rover_cluster_client.py +8 -8
  381. oci/rover/rover_entitlement_client.py +6 -6
  382. oci/rover/rover_node_client.py +15 -15
  383. oci/rover/shape_client.py +1 -1
  384. oci/rover/work_requests_client.py +5 -5
  385. oci/sch/connector_plugins_client.py +2 -2
  386. oci/sch/service_connector_client.py +12 -12
  387. oci/secrets/secrets_client.py +3 -3
  388. oci/security_attribute/security_attribute_client.py +18 -18
  389. oci/service_catalog/service_catalog_client.py +26 -26
  390. oci/service_manager_proxy/service_manager_proxy_client.py +2 -2
  391. oci/service_mesh/service_mesh_client.py +48 -48
  392. oci/stack_monitoring/stack_monitoring_client.py +87 -87
  393. oci/streaming/stream_admin_client.py +18 -18
  394. oci/streaming/stream_client.py +8 -8
  395. oci/tenant_manager_control_plane/domain_client.py +5 -5
  396. oci/tenant_manager_control_plane/domain_governance_client.py +5 -5
  397. oci/tenant_manager_control_plane/governance_client.py +2 -2
  398. oci/tenant_manager_control_plane/link_client.py +3 -3
  399. oci/tenant_manager_control_plane/orders_client.py +2 -2
  400. oci/tenant_manager_control_plane/organization_client.py +10 -10
  401. oci/tenant_manager_control_plane/recipient_invitation_client.py +5 -5
  402. oci/tenant_manager_control_plane/sender_invitation_client.py +5 -5
  403. oci/tenant_manager_control_plane/subscription_client.py +11 -11
  404. oci/tenant_manager_control_plane/work_request_client.py +4 -4
  405. oci/threat_intelligence/threatintel_client.py +5 -5
  406. oci/usage/resources_client.py +2 -2
  407. oci/usage/rewards_client.py +6 -6
  408. oci/usage/usagelimits_client.py +1 -1
  409. oci/usage_api/usageapi_client.py +33 -33
  410. oci/vault/vaults_client.py +13 -13
  411. oci/vbs_inst/vbs_instance_client.py +10 -10
  412. oci/version.py +1 -1
  413. oci/visual_builder/vb_instance_client.py +14 -14
  414. oci/vn_monitoring/vn_monitoring_client.py +12 -12
  415. oci/vulnerability_scanning/vulnerability_scanning_client.py +58 -58
  416. oci/waa/waa_client.py +13 -13
  417. oci/waa/work_request_client.py +4 -4
  418. oci/waas/redirect_client.py +6 -6
  419. oci/waas/waas_client.py +66 -66
  420. oci/waf/waf_client.py +24 -24
  421. oci/work_requests/work_request_client.py +4 -4
  422. oci/zpr/zpr_client.py +15 -15
  423. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/METADATA +6 -1
  424. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/RECORD +428 -313
  425. oci/database_management/models/disable_external_mysql_associated_service_details.py +0 -144
  426. oci/database_management/models/enable_external_mysql_associated_service_details.py +0 -144
  427. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/LICENSE.txt +0 -0
  428. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/THIRD_PARTY_LICENSES.txt +0 -0
  429. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/WHEEL +0 -0
  430. {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,852 @@
1
+ # coding: utf-8
2
+ # Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
3
+ # This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
4
+
5
+ """
6
+ ADK Main Agent models
7
+ """
8
+
9
+ import json
10
+ import time
11
+ from typing import Any, Callable, Dict, List, Optional, Union
12
+
13
+ from oci.addons.adk.agent_client import AgentClient
14
+ from oci.addons.adk.agent_error import AgentError, UserError
15
+ from oci.addons.adk.constants import MAX_STATUS_CHECK, FREEFORM_TAGS
16
+ from oci.addons.adk.logger import default_logger as logger
17
+ from oci.addons.adk.run.response import RunResponse
18
+ from oci.addons.adk.run.types import FunctionCall, PerformedAction, RequiredAction
19
+ from oci.addons.adk.tool import FunctionTool, Toolkit, tool
20
+ from oci.addons.adk.tool.utils import dedupe_tools_list, diff_local_and_remote_tool
21
+ from oci.addons.adk.tool.prebuilt import AgenticRagTool
22
+
23
+
24
+ class Agent:
25
+ """
26
+ An AI agent that can execute tasks using provided tools and instructions.
27
+
28
+ The agent maintains synchronization between local and remote tools, handles
29
+ function execution, and manages the interaction loop with the AI.
30
+ """
31
+
32
+ # Agent endpoint ID
33
+ agent_endpoint_id: str
34
+
35
+ # Agent client
36
+ _client: Optional[AgentClient] = None
37
+
38
+ # Base instructions for the agent
39
+ instructions: Optional[str] = None
40
+
41
+ # List of tools the agent can use
42
+ tools: Optional[
43
+ List[Union[Callable, FunctionTool, Toolkit, "Agent", AgenticRagTool]]
44
+ ] = None
45
+
46
+ # Optional name for the agent
47
+ name: Optional[str] = None
48
+
49
+ # Optional description for the agent
50
+ description: Optional[str] = None
51
+
52
+ def __init__(
53
+ self,
54
+ agent_endpoint_id: str,
55
+ client: Optional[AgentClient] = None,
56
+ instructions: str = "You are a helpful assistant",
57
+ tools: Optional[
58
+ List[Callable | FunctionTool | Toolkit | "Agent" | AgenticRagTool]
59
+ ] = None,
60
+ name: Optional[str] = None,
61
+ description: Optional[str] = None,
62
+ **kwargs: Dict[str, Any],
63
+ ) -> None:
64
+ """
65
+ Initialize an agent instance.
66
+
67
+ Args:
68
+ agent_endpoint_id: The agent endpoint ID
69
+ client: The agent client for API communication
70
+ instructions: The base instructions for the agent
71
+ tools: List of tools the agent can use
72
+ (functions, toolkits, or other agents)
73
+ name: Optional name for the agent
74
+ description: Optional description for the agent
75
+ """
76
+ self.agent_endpoint_id = agent_endpoint_id
77
+ self._client = client
78
+ self.instructions = instructions
79
+ self.tools = tools
80
+ self.name = name
81
+ self.description = description
82
+
83
+ # varibles not set up user
84
+ self._agent_details: Dict[str, Any] = {}
85
+ self._local_handler_functions: List[FunctionTool] = (
86
+ self._process_function_tools()
87
+ )
88
+ self._local_rag_tools: List[AgenticRagTool] = (
89
+ self._process_agentic_rag_tools()
90
+ )
91
+
92
+ # initialization
93
+ self._init_client()
94
+
95
+ @property
96
+ def client(self) -> AgentClient:
97
+ """
98
+ Get the agent client, raising an error if it's not initialized.
99
+
100
+ Returns:
101
+ The initialized agent client
102
+
103
+ Raises:
104
+ UserError: If the client is not initialized
105
+ """
106
+ if self._client is None:
107
+ raise UserError("Agent client is not initialized")
108
+ return self._client
109
+
110
+ @property
111
+ def agent_details(self) -> Dict[str, Any]:
112
+ """
113
+ Get the agent details.
114
+
115
+ Returns:
116
+ The agent details
117
+ """
118
+ if not self._agent_details:
119
+ self._fetch_and_cache_agent_details()
120
+ return self._agent_details
121
+
122
+ def setup(self) -> None:
123
+ """
124
+ Initialize the agent by
125
+ 1. checking agent details integrity,
126
+ 2. synchronizing agent to remote,
127
+ 3. synchronizing local and remote function tools.
128
+ 4. synchronizing local and remote rag tools.
129
+ """
130
+ self._check_agent_details_integrity()
131
+ self._sync_agent_to_remote()
132
+ self._sync_function_tools_to_remote()
133
+ self._sync_rag_tools_to_remote()
134
+
135
+ def run(
136
+ self,
137
+ input: str,
138
+ session_name: Optional[str] = None,
139
+ session_description: Optional[str] = None,
140
+ session_id: Optional[str] = None,
141
+ delete_session: Optional[bool] = False,
142
+ max_steps: int = 10,
143
+ on_fulfilled_required_action: Optional[
144
+ Callable[[RequiredAction, PerformedAction | None], None]
145
+ ] = None,
146
+ on_invoked_remote_service: Optional[
147
+ Callable[[Dict[str, Any], Dict[str, Any]], None]
148
+ ] = None,
149
+ **kwargs: Optional[Dict[str, Any]],
150
+ ) -> RunResponse:
151
+ """
152
+ Run the agent's react loop to process the user message.
153
+
154
+ Args:
155
+ input: The user input to process (required)
156
+ session_name: Name for the processing session
157
+ session_description: Description of the processing session
158
+ session_id: Optional session ID for the processing session
159
+ - if session_id is not provided,
160
+ the API contract means a new session should be created
161
+ - otherwise, the API contract means
162
+ we should reuse the provided session id
163
+ (for same session multi-turn chat)
164
+ delete_session: Optional flag to delete the session after run
165
+ (default: False)
166
+ max_steps: Maximum number of steps before terminating
167
+ on_fulfilled_required_action: Optional callback function
168
+ to handle fulfilled required actions
169
+ on_invoked_remote_service: Optional callback function
170
+ to handle invoked remote services
171
+ Returns:
172
+ RunResponse containing the final result
173
+ """
174
+ try:
175
+ # if session_id is not provided, create a new one
176
+ if session_id is None:
177
+ session_id = self.client.create_session(
178
+ agent_endpoint_id=self.agent_endpoint_id,
179
+ display_name=session_name,
180
+ description=session_description,
181
+ )
182
+ elif session_name or session_description:
183
+ logger.warning(
184
+ "session_id is provided, session_name and session_description will be ignored" # noqa: E501
185
+ )
186
+
187
+ # In case agent as tools, kwargs will be passed in, and
188
+ # we want to include them in the user input
189
+ user_message = f"{input} {kwargs}" if kwargs else input
190
+
191
+ response = self._handle_chat(
192
+ user_message=user_message,
193
+ session_id=session_id,
194
+ on_invoked_remote_service=on_invoked_remote_service,
195
+ )
196
+
197
+ step_count = 0
198
+ while self._has_required_actions(response) and step_count < max_steps:
199
+ performed_actions = self._handle_required_actions(
200
+ response, on_fulfilled_required_action
201
+ )
202
+ # put a dummy user message before server bug fix
203
+ # it should have been None
204
+ next_user_message = "null"
205
+ # next_user_message = None
206
+
207
+ time.sleep(2) # to avoid throttle by GenAI service
208
+ response = self._handle_chat(
209
+ user_message=next_user_message,
210
+ session_id=session_id,
211
+ performed_actions=performed_actions,
212
+ on_invoked_remote_service=on_invoked_remote_service,
213
+ )
214
+
215
+ step_count += 1
216
+
217
+ if step_count >= max_steps:
218
+ logger.warning(
219
+ f"Reached maximum number of steps ({max_steps}). Exiting loop."
220
+ )
221
+
222
+ return RunResponse(session_id=session_id, data=response)
223
+
224
+ except Exception as e:
225
+ logger.error(f"Error during agent execution: {e}", exc_info=True)
226
+ raise
227
+
228
+ finally:
229
+ if delete_session and session_id:
230
+ self.client.delete_session(
231
+ agent_endpoint_id=self.agent_endpoint_id,
232
+ session_id=session_id,
233
+ )
234
+
235
+ def as_tool(
236
+ self,
237
+ tool_name: str | None = None,
238
+ tool_description: str | None = None,
239
+ ) -> FunctionTool:
240
+ """
241
+ Convert this agent to a FunctionTool that can be used by other agents.
242
+
243
+ This allows agents to be composed and used as tools by other agents,
244
+ enabling complex hierarchical agent structures.
245
+
246
+ Args:
247
+ tool_name: Optional custom name for the tool. If not provided,
248
+ uses the agent's name or a default.
249
+ tool_description: Optional custom description for the tool. If not provided,
250
+ uses an empty string.
251
+
252
+ Returns:
253
+ A FunctionTool representing this agent
254
+ """
255
+ # Use provided tool name or agent name, or fall back to a default
256
+ name = (
257
+ tool_name or
258
+ self.name or
259
+ self.client.get_agent(self.agent_details["agent_id"]).get("display_name", None) or
260
+ "run_sub_agent"
261
+ )
262
+
263
+ # Use provided description, or fall back to an empty string
264
+ description = (
265
+ tool_description or
266
+ self.description or
267
+ self.client.get_agent(self.agent_details["agent_id"]).get("description", None) or
268
+ ""
269
+ )
270
+
271
+ # Create a decorated wrapper function using the @tool decorator
272
+ @tool(name=name, description=description)
273
+ def agent_run_wrapper(input: str, **kwargs) -> Dict[str, Any]:
274
+ """Execute this agent with the given user input and additional params."""
275
+ response = self.run(input=input, **kwargs)
276
+ return response.data
277
+
278
+ # Create a FunctionTool from the wrapper
279
+ return FunctionTool.from_callable(agent_run_wrapper)
280
+
281
+ def create_session(
282
+ self,
283
+ session_name: Optional[str] = None,
284
+ session_description: Optional[str] = None,
285
+ ) -> str:
286
+ """
287
+ Create a new session.
288
+ Wrapper method for client.create_session.
289
+
290
+ Args:
291
+ session_name: Name for the session
292
+ session_description: Description of the session
293
+
294
+ Returns:
295
+ The session ID
296
+ """
297
+ return self.client.create_session(
298
+ agent_endpoint_id=self.agent_endpoint_id,
299
+ display_name=session_name,
300
+ description=session_description,
301
+ )
302
+
303
+ def delete_session(
304
+ self,
305
+ session_id: str
306
+ ) -> None:
307
+ """
308
+ Delete a session.
309
+ Wrapper method for client.delete_session.
310
+
311
+ When to use:
312
+ - When you want to explicitly delete a session after the run is complete
313
+ - When the number of sessions exceeds the maximum allowed for the agent endpoint
314
+
315
+ Args:
316
+ session_id: The session ID
317
+ """
318
+ self.client.delete_session(
319
+ agent_endpoint_id=self.agent_endpoint_id,
320
+ session_id=session_id,
321
+ )
322
+
323
+ def print_local_agent_tools_details(self) -> None:
324
+ """Print the local agent tools details."""
325
+ logger.info(f"Found {len(self._local_handler_functions)} local tools")
326
+ for local_tool in self._local_handler_functions:
327
+ logger.info(local_tool.to_dict())
328
+
329
+ def print_remote_agent_details(self) -> None:
330
+ """Print the remote agent details."""
331
+ response = self.client.get_agent(self.agent_details["agent_id"])
332
+ logger.info(f"Agent details: {response}")
333
+
334
+ def print_remote_agent_endpoint_details(self) -> None:
335
+ """Print the agent endpoint details."""
336
+ response = self.client.get_agent_endpoint_details(self.agent_endpoint_id)
337
+ logger.info(f"Agent endpoint details: {response}")
338
+
339
+ def print_remote_agent_tools_details(
340
+ self, print_deleted_tools: bool = False
341
+ ) -> None:
342
+ """Print the agent tools details."""
343
+ tools = self.client.find_tools(
344
+ compartment_id=self.agent_details["compartment_id"],
345
+ agent_id=self.agent_details["agent_id"],
346
+ )
347
+ active_tools = [
348
+ tool for tool in tools if tool.get("lifecycle_state") == "ACTIVE"
349
+ ]
350
+ deleted_tools = [
351
+ tool for tool in tools if tool.get("lifecycle_state") == "DELETED"
352
+ ]
353
+ logger.info(
354
+ f"Found {len(active_tools)} active tools"
355
+ f"and {len(deleted_tools)} deleted tools"
356
+ )
357
+
358
+ if len(active_tools) > 0:
359
+ logger.info("Active tools:")
360
+ for active_tool in active_tools:
361
+ logger.info(active_tool)
362
+
363
+ if print_deleted_tools and len(deleted_tools) > 0:
364
+ logger.info("Deleted tools:")
365
+ for deleted_tool in deleted_tools:
366
+ logger.info(deleted_tool)
367
+
368
+ def wait_tool_active(self, tool_id: str) -> None:
369
+ """
370
+ Wait for the tool to be active
371
+ """
372
+ count = 0
373
+ while self.client.get_tool(tool_id).get("lifecycle_state") != "ACTIVE":
374
+ time.sleep(5)
375
+ logger.info(f"Waiting for tool {tool_id} to be active...")
376
+ count += 1
377
+ if count > MAX_STATUS_CHECK:
378
+ raise AgentError("Tool did not become active within the timeout period")
379
+
380
+ def wait_tool_delete(self, tool_id: str) -> None:
381
+ """
382
+ Wait for the tool to be deleted
383
+ """
384
+ count = 0
385
+ while self.client.get_tool(tool_id).get("lifecycle_state") != "DELETED":
386
+ time.sleep(5)
387
+ logger.info(f"Waiting for tool {tool_id} to be deleted...")
388
+ count += 1
389
+ if count > MAX_STATUS_CHECK:
390
+ raise AgentError("Tool did not become deleted within the timeout period")
391
+
392
+ def wait_agent_active(self) -> None:
393
+ """Wait for the agent to be active."""
394
+ count = 0
395
+ while (
396
+ self.client.get_agent(self.agent_details["agent_id"])
397
+ .get("lifecycle_state") != "ACTIVE"
398
+ ):
399
+ time.sleep(5)
400
+ logger.info(f"Waiting for agent {self.agent_details['agent_id']} to be active...")
401
+ count += 1
402
+ if count > MAX_STATUS_CHECK:
403
+ raise AgentError(
404
+ "Agent did not become active within the timeout period"
405
+ )
406
+
407
+ def _handle_chat(
408
+ self,
409
+ user_message: str,
410
+ session_id: str,
411
+ performed_actions: Optional[List[PerformedAction]] = None,
412
+ on_invoked_remote_service: Optional[
413
+ Callable[[Dict[str, Any], Dict[str, Any]], None]
414
+ ] = None,
415
+ ) -> Dict[str, Any]:
416
+ """
417
+ Handle a chat request.
418
+
419
+ Args:
420
+ user_message: The user message to display
421
+ session_id: The session ID
422
+ performed_actions: The performed actions
423
+ on_invoked_remote_service: Optional callback function
424
+ to handle invoked remote services
425
+
426
+ Returns:
427
+ The response from the agent
428
+ """
429
+ self._log_chat_request(user_message, session_id, performed_actions)
430
+
431
+ response = self.client.chat(
432
+ agent_endpoint_id=self.agent_endpoint_id,
433
+ session_id=session_id,
434
+ user_message=user_message,
435
+ performed_actions=performed_actions,
436
+ )
437
+
438
+ self._log_chat_response(response)
439
+
440
+ if on_invoked_remote_service:
441
+ on_invoked_remote_service(
442
+ {
443
+ "user_message": user_message,
444
+ "performed_actions": [
445
+ action.model_dump() for action in performed_actions
446
+ ]
447
+ if performed_actions
448
+ else None,
449
+ },
450
+ response,
451
+ )
452
+
453
+ return response
454
+
455
+ def _fetch_and_cache_agent_details(self) -> None:
456
+ """Fetch and cache the agent details."""
457
+ self._agent_details = self.client.get_agent_endpoint_details(self.agent_endpoint_id)
458
+
459
+ def _init_client(self) -> None:
460
+ """Initialize the client."""
461
+ if self._client is None:
462
+ self._client = AgentClient()
463
+
464
+ def _check_agent_details_integrity(self) -> None:
465
+ """Check the integrity of the agent details."""
466
+ logger.info("Checking integrity of agent details...")
467
+ if not self.agent_details.get("agent_id"):
468
+ raise AgentError("Agent needs to be setup first")
469
+
470
+ if self.agent_details.get("should_enable_session") is False:
471
+ raise AgentError("Agent endpoint is not session enabled")
472
+
473
+ if self.agent_details.get("lifecycle_state") != "ACTIVE":
474
+ raise AgentError(
475
+ f"Agent endpoint is not active, "
476
+ f"current state: {self.agent_details.get('lifecycle_state')}"
477
+ )
478
+
479
+ def _sync_agent_to_remote(self) -> None:
480
+ """Synchronize the local agent settings to the remote agent."""
481
+ logger.info("Checking synchronization of local and remote agent settings...")
482
+ response = self.client.get_agent(self.agent_details["agent_id"])
483
+ display_name = response.get("display_name", None)
484
+ description = response.get("description", None)
485
+ llm_config = response.get("llm_config", {}) or {}
486
+ routing_llm_customization = (
487
+ llm_config.get("routing_llm_customization", {}) or {}
488
+ )
489
+ instruction = routing_llm_customization.get("instruction", "") or ""
490
+ if (
491
+ instruction != self.instructions or
492
+ (self.name is not None and display_name != self.name) or
493
+ (self.description is not None and description != self.description)
494
+ ):
495
+ logger.info(
496
+ "Agent settings are not synchronized. Updating remote agent settings"
497
+ )
498
+ logger.debug(
499
+ f"Local agent settings: {self.name}, {self.description}, {self.instructions}",
500
+ f"Remote agent settings: {display_name}, {description}, {instruction}",
501
+ )
502
+ self.client.update_agent(
503
+ self.agent_details["agent_id"],
504
+ name=self.name,
505
+ description=self.description,
506
+ instructions=self.instructions,
507
+ )
508
+ self.wait_agent_active()
509
+
510
+ def _sync_function_tools_to_remote(self) -> None:
511
+ """
512
+ Synchronize local and remote function tools.
513
+
514
+ """
515
+ logger.info("Checking synchronization of local and remote function tools...")
516
+ local_func_tools = self._local_handler_functions
517
+ remote_func_tools = self.client.find_tools(
518
+ compartment_id=self.agent_details["compartment_id"],
519
+ agent_id=self.agent_details["agent_id"],
520
+ )
521
+ remote_func_tools = [
522
+ tool
523
+ for tool in remote_func_tools
524
+ if tool.get("lifecycle_state") == "ACTIVE" and
525
+ tool.get("tool_config", {})
526
+ .get("tool_config_type") == "FUNCTION_CALLING_TOOL_CONFIG"
527
+ ]
528
+ self._log_tool_counts(local_func_tools, remote_func_tools)
529
+ self._sync_local_and_remote_tools(local_func_tools, remote_func_tools)
530
+ return
531
+
532
+ def _sync_rag_tools_to_remote(self) -> None:
533
+ """
534
+ Synchronize local and remote agentic RAG tools.
535
+ """
536
+ logger.info("Checking synchronization of local and remote RAG tools...")
537
+ local_rag_tools = self._local_rag_tools
538
+ # Get existing remote RAG tools
539
+ remote_rag_tools = self.client.find_tools(
540
+ compartment_id=self.agent_details["compartment_id"],
541
+ agent_id=self.agent_details["agent_id"],
542
+ )
543
+ # Filter for active RAG tools with ADK tags
544
+ remote_rag_tools = [
545
+ tool
546
+ for tool in remote_rag_tools
547
+ if tool.get("lifecycle_state") == "ACTIVE" and
548
+ set(FREEFORM_TAGS.keys()).issubset(tool.get("freeform_tags", {}).keys()) and
549
+ tool.get("tool_config", {}).get("tool_config_type") == "RAG_TOOL_CONFIG"
550
+ ]
551
+ self._sync_local_and_remote_tools(local_rag_tools, remote_rag_tools)
552
+ return
553
+
554
+ def _sync_local_and_remote_tools(
555
+ self,
556
+ local_tools: List[FunctionTool] | List[AgenticRagTool],
557
+ remote_tools: List[Dict[str, Any]]
558
+ ) -> None:
559
+ """
560
+ Synchronize local and remote tools.
561
+ Local tools are considered the source of truth. This method will:
562
+ - Remove remote tools that don't exist locally
563
+ - Add local tools that don't exist remotely
564
+
565
+ Args:
566
+ local_tools: The local tools
567
+ types: List[FunctionTool] | List[AgenticRagTool]
568
+ remote_tools: The remote tools
569
+ types: List[Dict[str, Any]]
570
+ """
571
+ # Remove remote tools that don't exist locally
572
+ for remote_tool in remote_tools:
573
+ if all(
574
+ diff_local_and_remote_tool(local_tool, remote_tool)
575
+ for local_tool in local_tools
576
+ ):
577
+ logger.info(f"Removing remote tool {remote_tool.get('display_name', '')}...")
578
+ self.client.delete_tool(remote_tool["id"])
579
+ self.wait_tool_delete(remote_tool["id"])
580
+ # Add local tools to remote
581
+ for local_tool in local_tools:
582
+ if all(
583
+ diff_local_and_remote_tool(local_tool, remote_tool)
584
+ for remote_tool in remote_tools
585
+ ):
586
+ logger.info(f"Adding local tool {local_tool.name} to remote...")
587
+ if isinstance(local_tool, FunctionTool):
588
+ new_tool = self.client.add_function_tool(
589
+ local_tool,
590
+ compartment_id=self.agent_details["compartment_id"],
591
+ agent_id=self.agent_details["agent_id"],
592
+ )
593
+ elif isinstance(local_tool, AgenticRagTool):
594
+ new_tool = self.client.add_rag_tool(
595
+ local_tool,
596
+ compartment_id=self.agent_details["compartment_id"],
597
+ agent_id=self.agent_details["agent_id"],
598
+ )
599
+ new_tool_id = new_tool.get("id", "")
600
+ self.wait_tool_active(new_tool_id)
601
+ return
602
+
603
+ def _process_function_tools(self) -> List[FunctionTool]:
604
+ """
605
+ Convert all tools to FunctionTool format.
606
+ And de-duplicate tools
607
+
608
+ Returns:
609
+ List of processed FunctionTool objects
610
+ """
611
+ available_func_tools: List[FunctionTool] = []
612
+
613
+ if self.tools is not None:
614
+ for local_tool in self.tools:
615
+ if isinstance(local_tool, FunctionTool):
616
+ available_func_tools.append(local_tool)
617
+ elif callable(local_tool):
618
+ available_func_tools.append(FunctionTool.from_callable(local_tool))
619
+ elif isinstance(local_tool, Toolkit):
620
+ available_func_tools.extend(local_tool.functions.values())
621
+ elif isinstance(local_tool, Agent):
622
+ available_func_tools.append(local_tool.as_tool())
623
+ # de-duplicate tools
624
+ return dedupe_tools_list(available_func_tools)
625
+
626
+ def _process_agentic_rag_tools(self) -> List[AgenticRagTool]:
627
+ """
628
+ Convert all tools to AgenticRagTool format.
629
+ """
630
+ available_agentic_rag_tools: List[AgenticRagTool] = []
631
+ if self.tools is not None:
632
+ for local_tool in self.tools:
633
+ if isinstance(local_tool, AgenticRagTool):
634
+ available_agentic_rag_tools.append(local_tool)
635
+ # Check if there is more than one RAG tool for better user experience
636
+ if len(available_agentic_rag_tools) > 1:
637
+ logger.warning(
638
+ "Only one RAG tool is supported at the moment. "
639
+ "You can use multiple knowledge bases IDs in the same RAG tool."
640
+ )
641
+ # de-duplicate tools
642
+ return dedupe_tools_list(available_agentic_rag_tools)
643
+
644
+ @staticmethod
645
+ def _has_required_actions(response: Dict[str, Any]) -> bool:
646
+ """Check if the response contains required actions."""
647
+ return response.get("required_actions") is not None
648
+
649
+ def _handle_required_actions(
650
+ self,
651
+ response: Dict[str, Any],
652
+ on_fulfilled_required_action: Optional[
653
+ Callable[[RequiredAction, PerformedAction | None], None]
654
+ ] = None,
655
+ ) -> List[PerformedAction]:
656
+ """
657
+ Process and execute required actions from the response.
658
+
659
+ Args:
660
+ response: The response containing required actions
661
+ on_fulfilled_required_action: Optional callback function that will be called
662
+ with performed actions
663
+ Returns:
664
+ List of performed actions
665
+ """
666
+ required_actions = response.get("required_actions", [])
667
+ performed_actions = []
668
+
669
+ for action in required_actions:
670
+ required_action = RequiredAction.model_validate(action)
671
+ if (
672
+ required_action.required_action_type ==
673
+ "FUNCTION_CALLING_REQUIRED_ACTION"
674
+ ):
675
+ performed_action = self._execute_function_call(
676
+ required_action.function_call, required_action.action_id
677
+ )
678
+ if performed_action:
679
+ performed_actions.append(performed_action)
680
+ if on_fulfilled_required_action:
681
+ on_fulfilled_required_action(required_action, performed_action)
682
+
683
+ return performed_actions
684
+
685
+ def _execute_function_call(
686
+ self, function_call: FunctionCall, action_id: str
687
+ ) -> Optional[PerformedAction]:
688
+ """
689
+ Execute a single function call action.
690
+
691
+ Args:
692
+ function_call: The function call to execute
693
+ action_id: The ID of the action
694
+
695
+ Returns:
696
+ Dictionary containing the performed action details
697
+ or None if execution failed
698
+ """
699
+ try:
700
+ function_name = function_call.name
701
+ function_args = (
702
+ json.loads(function_call.arguments)
703
+ if isinstance(function_call.arguments, str)
704
+ else function_call.arguments
705
+ )
706
+
707
+ handler = None
708
+ for f in self._local_handler_functions:
709
+ if f.name == function_name:
710
+ handler = f
711
+ break
712
+
713
+ if not handler:
714
+ logger.info(f"No handler found for function: {function_name}")
715
+ return None
716
+
717
+ self._log_function_execution_start(
718
+ handler.name, handler.callable.__name__, function_args
719
+ )
720
+ result = handler.execute(function_args)
721
+ self._log_function_execution_result(result)
722
+
723
+ return PerformedAction(
724
+ action_id=action_id,
725
+ performed_action_type="FUNCTION_CALLING_PERFORMED_ACTION",
726
+ function_call_output=json.dumps(result),
727
+ )
728
+
729
+ except Exception as e:
730
+ logger.error(f"[red]Error executing function '{function_name}':[/red]")
731
+ logger.print_exception(show_locals=True)
732
+ return PerformedAction(
733
+ action_id=action_id,
734
+ performed_action_type="FUNCTION_CALLING_PERFORMED_ACTION",
735
+ function_call_output=str(e),
736
+ )
737
+
738
+ def _log_chat_request(
739
+ self,
740
+ message: str,
741
+ session_id: str,
742
+ performed_actions: Optional[List[PerformedAction]] = None,
743
+ ) -> None:
744
+ """
745
+ Log a chat to remote agent.
746
+
747
+ Args:
748
+ message: The user message to display
749
+ """
750
+ if not performed_actions:
751
+ actions = []
752
+ else:
753
+ actions = [action.model_dump(by_alias=True) for action in performed_actions]
754
+
755
+ message_text = (
756
+ f"(Local --> Remote)\n\n"
757
+ f"user message:\n"
758
+ f"[bold green]{message}[/bold green]\n\n"
759
+ f"performed actions by client:\n"
760
+ f"[bold magenta]{json.dumps(actions, indent=4)}[/bold magenta]\n\n" # noqa: E501
761
+ f"session id:\n"
762
+ f"[bold cyan]{session_id}[/bold cyan]"
763
+ )
764
+ logger.print(
765
+ message_text,
766
+ title="Chat request to remote agent",
767
+ border_style="blue",
768
+ expand=False,
769
+ )
770
+
771
+ def _log_chat_response(self, response: Dict[str, Any]) -> None:
772
+ """
773
+ Log a chat response from the remote agent.
774
+
775
+ Args:
776
+ response: The response containing the chat details
777
+ """
778
+
779
+ response_message = json.dumps(response.get("message"), indent=4)
780
+
781
+ message_text = (
782
+ f"(Local <-- Remote)\n\n"
783
+ f"agent message:\n[bold green]{response_message}[/bold green]\n\n"
784
+ f"required actions for client to take:\n"
785
+ f"[bold magenta]{json.dumps(response.get('required_actions', []), indent=4)}[/bold magenta]" # noqa: E501
786
+ )
787
+ logger.print(
788
+ message_text,
789
+ title="Chat response from remote agent",
790
+ border_style="blue",
791
+ expand=False,
792
+ )
793
+
794
+ def _log_function_execution_start(
795
+ self, function_tool_name: str, callable_name: str, function_args: Dict[str, Any]
796
+ ) -> None:
797
+ """
798
+ Log the start of a function execution.
799
+
800
+ Args:
801
+ function_tool_name: Name of the function tool being executed
802
+ callable_name: Name of the callable function
803
+ function_args: Arguments passed to the function
804
+ """
805
+ message_text = (
806
+ f"Agent function tool name:\n[bold cyan]{function_tool_name}[/bold cyan]\n\n" # noqa: E501
807
+ f"Agent function tool call arguments:\n[bold green]{function_args}[/bold green]\n\n" # noqa: E501
808
+ f"Mapped local handler function name:\n[bold cyan]{callable_name}[/bold cyan]" # noqa: E501
809
+ )
810
+ logger.print(
811
+ message_text,
812
+ title="Function call requested by agent and mapped local handler function", # noqa: E501
813
+ border_style="light_salmon3",
814
+ expand=False,
815
+ )
816
+
817
+ def _log_function_execution_result(self, result: Any) -> None:
818
+ """
819
+ Log the result of a function execution.
820
+
821
+ Args:
822
+ result: The result returned by the function
823
+ """
824
+ logger.print(
825
+ f"[bold green]{result}[/bold green]",
826
+ title="Obtained local function execution result",
827
+ border_style="light_salmon3",
828
+ expand=False,
829
+ )
830
+
831
+ def _log_tool_counts(
832
+ self, local_tools: List[FunctionTool], remote_tools: List[Dict[str, Any]]
833
+ ) -> None:
834
+ """
835
+ Log the number of local and remote function tools found.
836
+
837
+ Args:
838
+ local_tools: List of local FunctionTool objects
839
+ remote_tools: List of remote tool dictionaries
840
+ """
841
+ message_text = (
842
+ f"Local function tools ({len(local_tools)}):\n"
843
+ f"[bold green]{sorted([tool.name for tool in local_tools])}[/bold green]\n\n" # noqa: E501
844
+ f"Remote function tools ({len(remote_tools)}):\n"
845
+ f"[bold cyan]{sorted([tool['tool_config']['function']['name'] for tool in remote_tools])}[/bold cyan]" # noqa: E501
846
+ )
847
+ logger.print(
848
+ message_text,
849
+ title="Local and remote function tools found",
850
+ border_style="blue",
851
+ expand=False,
852
+ )