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.
- oci/__init__.py +2 -2
- oci/access_governance_cp/access_governance_cp_client.py +8 -8
- oci/addons/__init__.py +20 -0
- oci/addons/adk/__init__.py +13 -0
- oci/addons/adk/agent.py +852 -0
- oci/addons/adk/agent_client.py +682 -0
- oci/addons/adk/agent_error.py +36 -0
- oci/addons/adk/auth/__init__.py +5 -0
- oci/addons/adk/auth/auth_provider.py +28 -0
- oci/addons/adk/auth/factory.py +78 -0
- oci/addons/adk/auth/oci/__init__.py +5 -0
- oci/addons/adk/auth/oci/instance_principal.py +53 -0
- oci/addons/adk/auth/oci/resource_principal.py +53 -0
- oci/addons/adk/auth/oci/session.py +91 -0
- oci/addons/adk/auth/oci/user_principal.py +64 -0
- oci/addons/adk/constants.py +17 -0
- oci/addons/adk/logger.py +163 -0
- oci/addons/adk/run/__init__.py +5 -0
- oci/addons/adk/run/response.py +56 -0
- oci/addons/adk/run/types.py +32 -0
- oci/addons/adk/tool/__init__.py +13 -0
- oci/addons/adk/tool/function_tool.py +334 -0
- oci/addons/adk/tool/prebuilt/__init__.py +8 -0
- oci/addons/adk/tool/prebuilt/agentic_rag_tool.py +49 -0
- oci/addons/adk/tool/prebuilt/calculator_toolkit.py +104 -0
- oci/addons/adk/tool/tool.py +37 -0
- oci/addons/adk/tool/toolkit.py +189 -0
- oci/addons/adk/tool/utils.py +120 -0
- oci/addons/adk/util.py +325 -0
- oci/adm/application_dependency_management_client.py +36 -36
- oci/ai_anomaly_detection/anomaly_detection_client.py +36 -36
- oci/ai_document/ai_service_document_client.py +26 -26
- oci/ai_language/ai_service_language_client.py +44 -44
- oci/ai_speech/ai_service_speech_client.py +19 -19
- oci/ai_vision/ai_service_vision_client.py +28 -28
- oci/analytics/analytics_client.py +24 -24
- oci/announcements_service/announcement_client.py +5 -5
- oci/announcements_service/announcement_subscription_client.py +9 -9
- oci/announcements_service/announcements_preferences_client.py +4 -4
- oci/announcements_service/service_client.py +1 -1
- oci/apigateway/api_gateway_client.py +21 -21
- oci/apigateway/deployment_client.py +6 -6
- oci/apigateway/gateway_client.py +6 -6
- oci/apigateway/subscribers_client.py +6 -6
- oci/apigateway/usage_plans_client.py +6 -6
- oci/apigateway/work_requests_client.py +5 -5
- oci/apm_config/config_client.py +12 -12
- oci/apm_control_plane/apm_domain_client.py +14 -14
- oci/apm_synthetics/apm_synthetic_client.py +28 -28
- oci/apm_traces/attributes_client.py +8 -8
- oci/apm_traces/query_client.py +2 -2
- oci/apm_traces/trace_client.py +4 -4
- oci/appmgmt_control/appmgmt_control_client.py +8 -8
- oci/artifacts/artifacts_client.py +32 -32
- oci/audit/audit_client.py +3 -3
- oci/autoscaling/auto_scaling_client.py +11 -11
- oci/bastion/bastion_client.py +15 -15
- oci/bds/bds_client.py +84 -84
- oci/blockchain/blockchain_platform_client.py +27 -27
- oci/budget/budget_client.py +10 -10
- oci/capacity_management/capacity_management_client.py +32 -32
- oci/certificates/certificates_client.py +5 -5
- oci/certificates_management/certificates_management_client.py +32 -32
- oci/cims/incident_client.py +6 -6
- oci/cloud_bridge/common_client.py +5 -5
- oci/cloud_bridge/discovery_client.py +15 -15
- oci/cloud_bridge/inventory_client.py +16 -16
- oci/cloud_bridge/ocb_agent_svc_client.py +23 -23
- oci/cloud_guard/cloud_guard_client.py +155 -155
- oci/cloud_migrations/migration_client.py +43 -43
- oci/cluster_placement_groups/cluster_placement_groups_cp_client.py +13 -13
- oci/compute_cloud_at_customer/compute_cloud_at_customer_client.py +12 -12
- oci/compute_instance_agent/compute_instance_agent_client.py +6 -6
- oci/compute_instance_agent/plugin_client.py +2 -2
- oci/compute_instance_agent/pluginconfig_client.py +1 -1
- oci/container_engine/container_engine_client.py +46 -46
- oci/container_instances/container_instance_client.py +18 -18
- oci/core/blockstorage_client.py +60 -60
- oci/core/compute_client.py +117 -117
- oci/core/compute_management_client.py +32 -32
- oci/core/virtual_network_client.py +258 -258
- oci/dashboard_service/dashboard_client.py +6 -6
- oci/dashboard_service/dashboard_group_client.py +6 -6
- oci/data_catalog/data_catalog_client.py +149 -149
- oci/data_flow/data_flow_client.py +45 -45
- oci/data_integration/data_integration_client.py +163 -163
- oci/data_labeling_service/data_labeling_management_client.py +17 -17
- oci/data_labeling_service_dataplane/data_labeling_client.py +15 -15
- oci/data_safe/data_safe_client.py +317 -317
- oci/data_science/data_science_client.py +145 -145
- oci/database/database_client.py +745 -469
- oci/database/models/__init__.py +2 -0
- oci/database/models/autonomous_db_version_summary.py +31 -0
- oci/database/models/backup.py +4 -2
- oci/database/models/backup_summary.py +4 -2
- oci/database/models/create_external_backup_job_details.py +4 -4
- oci/database/models/db_system.py +4 -2
- oci/database/models/db_system_summary.py +4 -2
- oci/database/models/db_system_upgrade_summary.py +152 -0
- oci/database/models/external_container_database.py +4 -2
- oci/database/models/external_container_database_summary.py +4 -2
- oci/database/models/external_database_base.py +4 -2
- oci/database/models/external_non_container_database.py +4 -2
- oci/database/models/external_non_container_database_summary.py +4 -2
- oci/database/models/external_pluggable_database.py +4 -2
- oci/database/models/external_pluggable_database_summary.py +4 -2
- oci/database_management/db_management_client.py +356 -230
- oci/database_management/db_management_client_composite_operations.py +44 -0
- oci/database_management/diagnosability_client.py +4 -4
- oci/database_management/managed_my_sql_databases_client.py +7 -247
- oci/database_management/models/__init__.py +0 -4
- oci/database_management/models/database_diagnostics_and_management_feature_details.py +35 -4
- oci/database_management/models/disable_database_management_feature_details.py +33 -2
- oci/database_management/models/disable_external_container_database_management_feature_details.py +33 -2
- oci/database_management/models/discovered_external_database.py +64 -2
- oci/database_management/models/exadata_infrastructure_lifecycle_state_values.py +40 -36
- oci/database_management/models/external_database_diagnostics_and_management_feature_details.py +64 -2
- oci/database_management/models/managed_database.py +2 -4
- oci/database_management/models/managed_database_summary.py +2 -4
- oci/database_management/models/modify_database_management_feature_details.py +1 -1
- oci/database_management/perfhub_client.py +1 -1
- oci/database_management/sql_tuning_client.py +17 -17
- oci/database_migration/database_migration_client.py +42 -42
- oci/database_tools/database_tools_client.py +23 -23
- oci/dblm/db_life_cycle_management_client.py +14 -14
- oci/delegate_access_control/delegate_access_control_client.py +26 -26
- oci/delegate_access_control/work_request_client.py +4 -4
- oci/demand_signal/occ_demand_signal_client.py +7 -7
- oci/desktops/desktop_service_client.py +21 -21
- oci/devops/devops_client.py +141 -141
- oci/disaster_recovery/disaster_recovery_client.py +31 -31
- oci/distributed_database/__init__.py +20 -0
- oci/distributed_database/distributed_autonomous_db_service_client.py +2315 -0
- oci/distributed_database/distributed_autonomous_db_service_client_composite_operations.py +605 -0
- oci/distributed_database/distributed_db_private_endpoint_service_client.py +944 -0
- oci/distributed_database/distributed_db_private_endpoint_service_client_composite_operations.py +238 -0
- oci/distributed_database/distributed_db_service_client.py +2435 -0
- oci/distributed_database/distributed_db_service_client_composite_operations.py +647 -0
- oci/distributed_database/distributed_db_work_request_service_client.py +654 -0
- oci/distributed_database/distributed_db_work_request_service_client_composite_operations.py +26 -0
- oci/distributed_database/models/__init__.py +158 -0
- oci/distributed_database/models/add_distributed_autonomous_database_gds_control_node_details.py +105 -0
- oci/distributed_database/models/add_distributed_database_gds_control_node_details.py +105 -0
- oci/distributed_database/models/catalog_peer_with_dedicated_infra.py +331 -0
- oci/distributed_database/models/catalog_peer_with_exadb_xs.py +331 -0
- oci/distributed_database/models/change_distributed_autonomous_database_compartment_details.py +74 -0
- oci/distributed_database/models/change_distributed_database_compartment_details.py +74 -0
- oci/distributed_database/models/change_distributed_database_private_endpoint_compartment_details.py +74 -0
- oci/distributed_database/models/change_distributed_db_backup_config_details.py +66 -0
- oci/distributed_database/models/configure_distributed_autonomous_database_gsms_details.py +103 -0
- oci/distributed_database/models/configure_distributed_database_gsms_details.py +103 -0
- oci/distributed_database/models/create_distributed_autonomous_database_catalog_details.py +101 -0
- oci/distributed_database/models/create_distributed_autonomous_database_catalog_with_dedicated_infra_details.py +342 -0
- oci/distributed_database/models/create_distributed_autonomous_database_details.py +799 -0
- oci/distributed_database/models/create_distributed_autonomous_database_shard_details.py +101 -0
- oci/distributed_database/models/create_distributed_autonomous_database_shard_with_dedicated_infra_details.py +377 -0
- oci/distributed_database/models/create_distributed_database_catalog_details.py +99 -0
- oci/distributed_database/models/create_distributed_database_catalog_with_exadb_xs_details.py +282 -0
- oci/distributed_database/models/create_distributed_database_details.py +810 -0
- oci/distributed_database/models/create_distributed_database_private_endpoint_details.py +260 -0
- oci/distributed_database/models/create_distributed_database_shard_details.py +99 -0
- oci/distributed_database/models/create_distributed_database_shard_with_exadb_xs_details.py +282 -0
- oci/distributed_database/models/distributed_autonomous_database.py +1143 -0
- oci/distributed_database/models/distributed_autonomous_database_associated_with_private_endpoint.py +105 -0
- oci/distributed_database/models/distributed_autonomous_database_catalog.py +194 -0
- oci/distributed_database/models/distributed_autonomous_database_catalog_with_dedicated_infra.py +559 -0
- oci/distributed_database/models/distributed_autonomous_database_collection.py +70 -0
- oci/distributed_database/models/distributed_autonomous_database_connection_string.py +70 -0
- oci/distributed_database/models/distributed_autonomous_database_gsm.py +385 -0
- oci/distributed_database/models/distributed_autonomous_database_gsm_image.py +105 -0
- oci/distributed_database/models/distributed_autonomous_database_shard.py +194 -0
- oci/distributed_database/models/distributed_autonomous_database_shard_with_dedicated_infra.py +592 -0
- oci/distributed_database/models/distributed_autonomous_database_summary.py +935 -0
- oci/distributed_database/models/distributed_autonomous_db_metadata.py +70 -0
- oci/distributed_database/models/distributed_database.py +1154 -0
- oci/distributed_database/models/distributed_database_associated_with_private_endpoint.py +105 -0
- oci/distributed_database/models/distributed_database_catalog.py +192 -0
- oci/distributed_database/models/distributed_database_catalog_with_exadb_xs.py +466 -0
- oci/distributed_database/models/distributed_database_collection.py +70 -0
- oci/distributed_database/models/distributed_database_gsm.py +385 -0
- oci/distributed_database/models/distributed_database_private_endpoint.py +639 -0
- oci/distributed_database/models/distributed_database_private_endpoint_collection.py +70 -0
- oci/distributed_database/models/distributed_database_private_endpoint_summary.py +479 -0
- oci/distributed_database/models/distributed_database_shard.py +192 -0
- oci/distributed_database/models/distributed_database_shard_with_exadb_xs.py +499 -0
- oci/distributed_database/models/distributed_database_summary.py +904 -0
- oci/distributed_database/models/distributed_db_backup_config.py +536 -0
- oci/distributed_database/models/distributed_db_backup_destination.py +362 -0
- oci/distributed_database/models/distributed_db_connection_string.py +70 -0
- oci/distributed_database/models/distributed_db_gsm_image.py +105 -0
- oci/distributed_database/models/distributed_db_metadata.py +70 -0
- oci/distributed_database/models/generate_distributed_autonomous_database_wallet_details.py +70 -0
- oci/distributed_database/models/generate_distributed_database_wallet_details.py +70 -0
- oci/distributed_database/models/patch_distributed_autonomous_database_details.py +73 -0
- oci/distributed_database/models/patch_distributed_database_details.py +73 -0
- oci/distributed_database/models/patch_insert_instruction.py +87 -0
- oci/distributed_database/models/patch_instruction.py +154 -0
- oci/distributed_database/models/patch_merge_instruction.py +95 -0
- oci/distributed_database/models/patch_remove_instruction.py +57 -0
- oci/distributed_database/models/shard_peer_with_dedicated_infra.py +331 -0
- oci/distributed_database/models/shard_peer_with_exadb_xs.py +331 -0
- oci/distributed_database/models/update_distributed_autonomous_database_details.py +136 -0
- oci/distributed_database/models/update_distributed_database_details.py +136 -0
- oci/distributed_database/models/update_distributed_database_private_endpoint_details.py +198 -0
- oci/distributed_database/models/upload_distributed_autonomous_database_signed_certificate_and_generate_wallet_details.py +71 -0
- oci/distributed_database/models/upload_distributed_database_signed_certificate_and_generate_wallet_details.py +71 -0
- oci/distributed_database/models/work_request.py +516 -0
- oci/distributed_database/models/work_request_error.py +134 -0
- oci/distributed_database/models/work_request_error_collection.py +70 -0
- oci/distributed_database/models/work_request_log_entry.py +101 -0
- oci/distributed_database/models/work_request_log_entry_collection.py +70 -0
- oci/distributed_database/models/work_request_resource.py +232 -0
- oci/distributed_database/models/work_request_summary.py +516 -0
- oci/distributed_database/models/work_request_summary_collection.py +70 -0
- oci/dns/dns_client.py +54 -54
- oci/dts/appliance_export_job_client.py +6 -6
- oci/dts/shipping_vendors_client.py +1 -1
- oci/dts/transfer_appliance_client.py +8 -8
- oci/dts/transfer_appliance_entitlement_client.py +3 -3
- oci/dts/transfer_device_client.py +5 -5
- oci/dts/transfer_job_client.py +6 -6
- oci/dts/transfer_package_client.py +7 -7
- oci/em_warehouse/em_warehouse_client.py +13 -13
- oci/email/email_client.py +31 -31
- oci/email_data_plane/email_dp_client.py +1 -1
- oci/events/events_client.py +6 -6
- oci/file_storage/file_storage_client.py +74 -74
- oci/fleet_apps_management/fleet_apps_management_admin_client.py +27 -27
- oci/fleet_apps_management/fleet_apps_management_catalog_client.py +7 -7
- oci/fleet_apps_management/fleet_apps_management_client.py +32 -32
- oci/fleet_apps_management/fleet_apps_management_maintenance_window_client.py +5 -5
- oci/fleet_apps_management/fleet_apps_management_operations_client.py +29 -29
- oci/fleet_apps_management/fleet_apps_management_provision_client.py +6 -6
- oci/fleet_apps_management/fleet_apps_management_runbooks_client.py +19 -19
- oci/fleet_apps_management/fleet_apps_management_work_request_client.py +4 -4
- oci/fleet_software_update/fleet_software_update_client.py +46 -46
- oci/functions/functions_invoke_client.py +1 -1
- oci/functions/functions_management_client.py +16 -16
- oci/fusion_apps/fusion_applications_client.py +41 -41
- oci/generative_ai/generative_ai_client.py +22 -22
- oci/generative_ai/models/create_dedicated_ai_cluster_details.py +4 -0
- oci/generative_ai/models/dedicated_ai_cluster.py +11 -3
- oci/generative_ai_agent/generative_ai_agent_client.py +38 -38
- oci/generative_ai_agent_runtime/generative_ai_agent_runtime_client.py +6 -6
- oci/generative_ai_inference/generative_ai_inference_client.py +6 -6
- oci/generic_artifacts_content/generic_artifacts_content_client.py +3 -3
- oci/globally_distributed_database/sharded_database_service_client.py +58 -58
- oci/golden_gate/golden_gate_client.py +89 -89
- oci/governance_rules_control_plane/governance_rule_client.py +15 -15
- oci/governance_rules_control_plane/work_request_client.py +5 -5
- oci/healthchecks/health_checks_client.py +17 -17
- oci/identity/identity_client.py +145 -145
- oci/identity_data_plane/dataplane_client.py +2 -2
- oci/identity_domains/identity_domains_client.py +311 -311
- oci/integration/integration_instance_client.py +19 -19
- oci/jms/java_management_service_client.py +79 -79
- oci/jms_java_downloads/java_download_client.py +25 -25
- oci/key_management/ekm_client.py +5 -5
- oci/key_management/kms_crypto_client.py +6 -6
- oci/key_management/kms_hsm_cluster_client.py +12 -12
- oci/key_management/kms_management_client.py +21 -21
- oci/key_management/kms_vault_client.py +14 -14
- oci/license_manager/license_manager_client.py +18 -18
- oci/limits/limits_client.py +4 -4
- oci/limits/quotas_client.py +7 -7
- oci/load_balancer/load_balancer_client.py +61 -61
- oci/lockbox/lockbox_client.py +24 -24
- oci/log_analytics/log_analytics_client.py +200 -200
- oci/logging/logging_management_client.py +30 -30
- oci/loggingingestion/logging_client.py +1 -1
- oci/loggingsearch/log_search_client.py +1 -1
- oci/lustre_file_storage/lustre_file_storage_client.py +11 -11
- oci/management_agent/management_agent_client.py +28 -28
- oci/management_dashboard/dashx_apis_client.py +14 -14
- oci/marketplace/account_client.py +2 -2
- oci/marketplace/marketplace_client.py +30 -30
- oci/marketplace_private_offer/attachment_client.py +5 -5
- oci/marketplace_private_offer/offer_client.py +6 -6
- oci/marketplace_publisher/attachment_client.py +5 -5
- oci/marketplace_publisher/marketplace_publisher_client.py +71 -71
- oci/marketplace_publisher/offer_client.py +6 -6
- oci/media_services/media_services_client.py +60 -60
- oci/media_services/media_stream_client.py +2 -2
- oci/mngdmac/mac_device_client.py +3 -3
- oci/mngdmac/mac_order_client.py +11 -11
- oci/model_deployment/__init__.py +14 -0
- oci/model_deployment/model_deployment_client.py +331 -0
- oci/model_deployment/model_deployment_client_composite_operations.py +26 -0
- oci/model_deployment/models/__init__.py +14 -0
- oci/model_deployment/models/inference_result.py +70 -0
- oci/monitoring/monitoring_client.py +18 -18
- oci/mysql/channels_client.py +7 -7
- oci/mysql/db_backups_client.py +7 -7
- oci/mysql/db_system_client.py +17 -17
- oci/mysql/models/create_db_system_details.py +31 -0
- oci/mysql/models/db_system.py +31 -0
- oci/mysql/models/db_system_snapshot.py +31 -0
- oci/mysql/models/replica.py +31 -0
- oci/mysql/models/replica_overrides.py +33 -2
- oci/mysql/models/replica_summary.py +31 -0
- oci/mysql/models/update_db_system_details.py +31 -0
- oci/mysql/mysqlaas_client.py +7 -7
- oci/mysql/replicas_client.py +5 -5
- oci/mysql/work_requests_client.py +4 -4
- oci/network_firewall/network_firewall_client.py +86 -86
- oci/network_load_balancer/network_load_balancer_client.py +35 -35
- oci/nosql/nosql_client.py +24 -24
- oci/object_storage/object_storage_client.py +55 -55
- oci/oce/oce_instance_client.py +10 -10
- oci/oci_control_center/occ_metrics_client.py +3 -3
- oci/ocvp/cluster_client.py +5 -5
- oci/ocvp/esxi_host_client.py +8 -8
- oci/ocvp/sddc_client.py +14 -14
- oci/ocvp/work_request_client.py +4 -4
- oci/oda/management_client.py +59 -59
- oci/oda/oda_client.py +17 -17
- oci/oda/odapackage_client.py +7 -7
- oci/onesubscription/billing_schedule_client.py +1 -1
- oci/onesubscription/commitment_client.py +2 -2
- oci/onesubscription/computed_usage_client.py +3 -3
- oci/onesubscription/invoice_summary_client.py +2 -2
- oci/onesubscription/organization_subscription_client.py +1 -1
- oci/onesubscription/ratecard_client.py +1 -1
- oci/onesubscription/subscribed_service_client.py +2 -2
- oci/onesubscription/subscription_client.py +1 -1
- oci/ons/notification_control_plane_client.py +6 -6
- oci/ons/notification_data_plane_client.py +10 -10
- oci/opa/opa_instance_client.py +13 -13
- oci/opensearch/models/__init__.py +2 -0
- oci/opensearch/models/create_opensearch_cluster_details.py +291 -0
- oci/opensearch/models/create_opensearch_cluster_pipeline_details.py +31 -0
- oci/opensearch/models/opensearch_cluster.py +291 -0
- oci/opensearch/models/opensearch_cluster_pipeline.py +31 -0
- oci/opensearch/models/opensearch_cluster_pipeline_summary.py +31 -0
- oci/opensearch/models/resize_opensearch_cluster_horizontal_details.py +31 -0
- oci/opensearch/models/resize_opensearch_cluster_vertical_details.py +217 -0
- oci/opensearch/models/shapes_details.py +70 -0
- oci/opensearch/models/update_cluster_specs_details.py +186 -0
- oci/opensearch/models/update_opensearch_cluster_pipeline_details.py +31 -0
- oci/opensearch/opensearch_cluster_backup_client.py +4 -4
- oci/opensearch/opensearch_cluster_client.py +87 -16
- oci/opensearch/opensearch_cluster_pipeline_client.py +5 -5
- oci/operator_access_control/access_requests_client.py +10 -10
- oci/operator_access_control/operator_actions_client.py +2 -2
- oci/operator_access_control/operator_control_assignment_client.py +8 -8
- oci/operator_access_control/operator_control_client.py +6 -6
- oci/opsi/operations_insights_client.py +181 -181
- oci/optimizer/optimizer_client.py +26 -26
- oci/os_management/event_client.py +8 -8
- oci/os_management/os_management_client.py +69 -69
- oci/os_management_hub/event_client.py +8 -8
- oci/os_management_hub/lifecycle_environment_client.py +13 -13
- oci/os_management_hub/managed_instance_client.py +33 -33
- oci/os_management_hub/managed_instance_group_client.py +26 -26
- oci/os_management_hub/management_station_client.py +10 -10
- oci/os_management_hub/onboarding_client.py +13 -13
- oci/os_management_hub/reporting_managed_instance_client.py +3 -3
- oci/os_management_hub/scheduled_job_client.py +7 -7
- oci/os_management_hub/software_source_client.py +33 -33
- oci/os_management_hub/work_request_client.py +5 -5
- oci/osp_gateway/address_rule_service_client.py +1 -1
- oci/osp_gateway/address_service_client.py +2 -2
- oci/osp_gateway/invoice_service_client.py +5 -5
- oci/osp_gateway/subscription_service_client.py +5 -5
- oci/osub_billing_schedule/billing_schedule_client.py +1 -1
- oci/osub_organization_subscription/organization_subscription_client.py +1 -1
- oci/osub_subscription/commitment_client.py +2 -2
- oci/osub_subscription/ratecard_client.py +1 -1
- oci/osub_subscription/subscription_client.py +1 -1
- oci/osub_usage/computed_usage_client.py +3 -3
- oci/psql/postgresql_client.py +34 -34
- oci/queue/queue_admin_client.py +11 -11
- oci/queue/queue_client.py +8 -8
- oci/recovery/database_recovery_client.py +26 -26
- oci/redis/redis_cluster_client.py +12 -12
- oci/resource_manager/resource_manager_client.py +52 -52
- oci/resource_scheduler/schedule_client.py +14 -14
- oci/resource_search/resource_search_client.py +3 -3
- oci/rover/rover_bundle_client.py +8 -8
- oci/rover/rover_cluster_client.py +8 -8
- oci/rover/rover_entitlement_client.py +6 -6
- oci/rover/rover_node_client.py +15 -15
- oci/rover/shape_client.py +1 -1
- oci/rover/work_requests_client.py +5 -5
- oci/sch/connector_plugins_client.py +2 -2
- oci/sch/service_connector_client.py +12 -12
- oci/secrets/secrets_client.py +3 -3
- oci/security_attribute/security_attribute_client.py +18 -18
- oci/service_catalog/service_catalog_client.py +26 -26
- oci/service_manager_proxy/service_manager_proxy_client.py +2 -2
- oci/service_mesh/service_mesh_client.py +48 -48
- oci/stack_monitoring/stack_monitoring_client.py +87 -87
- oci/streaming/stream_admin_client.py +18 -18
- oci/streaming/stream_client.py +8 -8
- oci/tenant_manager_control_plane/domain_client.py +5 -5
- oci/tenant_manager_control_plane/domain_governance_client.py +5 -5
- oci/tenant_manager_control_plane/governance_client.py +2 -2
- oci/tenant_manager_control_plane/link_client.py +3 -3
- oci/tenant_manager_control_plane/orders_client.py +2 -2
- oci/tenant_manager_control_plane/organization_client.py +10 -10
- oci/tenant_manager_control_plane/recipient_invitation_client.py +5 -5
- oci/tenant_manager_control_plane/sender_invitation_client.py +5 -5
- oci/tenant_manager_control_plane/subscription_client.py +11 -11
- oci/tenant_manager_control_plane/work_request_client.py +4 -4
- oci/threat_intelligence/threatintel_client.py +5 -5
- oci/usage/resources_client.py +2 -2
- oci/usage/rewards_client.py +6 -6
- oci/usage/usagelimits_client.py +1 -1
- oci/usage_api/usageapi_client.py +33 -33
- oci/vault/vaults_client.py +13 -13
- oci/vbs_inst/vbs_instance_client.py +10 -10
- oci/version.py +1 -1
- oci/visual_builder/vb_instance_client.py +14 -14
- oci/vn_monitoring/vn_monitoring_client.py +12 -12
- oci/vulnerability_scanning/vulnerability_scanning_client.py +58 -58
- oci/waa/waa_client.py +13 -13
- oci/waa/work_request_client.py +4 -4
- oci/waas/redirect_client.py +6 -6
- oci/waas/waas_client.py +66 -66
- oci/waf/waf_client.py +24 -24
- oci/work_requests/work_request_client.py +4 -4
- oci/zpr/zpr_client.py +15 -15
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/METADATA +6 -1
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/RECORD +428 -313
- oci/database_management/models/disable_external_mysql_associated_service_details.py +0 -144
- oci/database_management/models/enable_external_mysql_associated_service_details.py +0 -144
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/LICENSE.txt +0 -0
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/THIRD_PARTY_LICENSES.txt +0 -0
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/WHEEL +0 -0
- {oci-2.151.0.dist-info → oci-2.152.1.dist-info}/top_level.txt +0 -0
oci/addons/adk/agent.py
ADDED
@@ -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
|
+
)
|