Bug: refactor(success_based): add support for exploration




diff --git a/crates/api_models/src/open_router.rs b/crates/api_models/src/open_router.rs
index f15d9cbcfeb..cfcb45ef97b 100644
--- a/crates/api_models/src/open_router.rs
+++ b/crates/api_models/src/open_router.rs
@@ -62,6 +62,7 @@ pub struct PaymentInfo {
 pub struct DecidedGateway {
     pub gateway_priority_map: Option<HashMap<String, f64>>,
     pub debit_routing_output: Option<DebitRoutingOutput>,
+    pub routing_approach: String,
 }
 
 #[derive(Debug, Serialize, Deserialize, PartialEq)]
diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs
index 12075935cd4..a247e6ad9ca 100644
--- a/crates/api_models/src/routing.rs
+++ b/crates/api_models/src/routing.rs
@@ -944,6 +944,7 @@ impl Default for SuccessBasedRoutingConfig {
                     max_total_count: Some(5),
                 }),
                 specificity_level: SuccessRateSpecificityLevel::default(),
+                exploration_percent: Some(20.0),
             }),
             decision_engine_configs: None,
         }
@@ -969,6 +970,7 @@ pub struct SuccessBasedRoutingConfigBody {
     pub current_block_threshold: Option<CurrentBlockThreshold>,
     #[serde(default)]
     pub specificity_level: SuccessRateSpecificityLevel,
+    pub exploration_percent: Option<f64>,
 }
 
 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
@@ -1094,7 +1096,10 @@ impl SuccessBasedRoutingConfigBody {
                 .as_mut()
                 .map(|threshold| threshold.update(current_block_threshold));
         }
-        self.specificity_level = new.specificity_level
+        self.specificity_level = new.specificity_level;
+        if let Some(exploration_percent) = new.exploration_percent {
+            self.exploration_percent = Some(exploration_percent);
+        }
     }
 }
 
diff --git a/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs b/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
index 278a2b50d15..b63f435327e 100644
--- a/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
+++ b/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
@@ -290,6 +290,7 @@ impl ForeignTryFrom<SuccessBasedRoutingConfigBody> for CalSuccessRateConfig {
                 SuccessRateSpecificityLevel::Merchant => Some(ProtoSpecificityLevel::Entity.into()),
                 SuccessRateSpecificityLevel::Global => Some(ProtoSpecificityLevel::Global.into()),
             },
+            exploration_percent: config.exploration_percent,
         })
     }
 }
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index 2b851c192b0..265a518f244 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -1776,10 +1776,7 @@ pub async fn perform_decide_gateway_call_with_open_router(
                 ))?;
 
             if let Some(gateway_priority_map) = decided_gateway.gateway_priority_map {
-                logger::debug!(
-                    "open_router decide_gateway call response: {:?}",
-                    gateway_priority_map
-                );
+                logger::debug!(gateway_priority_map=?gateway_priority_map, routing_approach=decided_gateway.routing_approach, "open_router decide_gateway call response");
                 routable_connectors.sort_by(|connector_choice_a, connector_choice_b| {
                     let connector_choice_a_score = gateway_priority_map
                         .get(&connector_choice_a.to_string())
diff --git a/proto/success_rate.proto b/proto/success_rate.proto
index 17d566af356..efdd439cac9 100644
--- a/proto/success_rate.proto
+++ b/proto/success_rate.proto
@@ -23,6 +23,7 @@ message CalSuccessRateConfig {
     uint32 min_aggregates_size = 1;
     double default_success_rate = 2;
     optional SuccessRateSpecificityLevel specificity_level = 3;
+    optional double exploration_percent = 4;
 }
 
 enum SuccessRateSpecificityLevel {
@@ -32,6 +33,12 @@ enum SuccessRateSpecificityLevel {
 
 message CalSuccessRateResponse {
     repeated LabelWithScore labels_with_score = 1;
+    RoutingApproach routing_approach = 2;
+}
+
+enum RoutingApproach {
+    EXPLORATION = 0;
+    EXPLOITATION = 1;
 }
 
 message LabelWithScore {

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Original PR - https://github.com/juspay/hyperswitch/pull/8158

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
