use std::time::Duration;
use crate::provider::config::ProviderConfig;
pub(super) const DEFAULT_TIMEOUT_SECS: u64 = 60;
pub(super) fn encode_path_segment(s: &str) -> String {
let mut encoded = String::with_capacity(s.len() * 2);
for byte in s.bytes() {
match byte {
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
encoded.push(byte as char);
}
_ => {
encoded.push('%');
encoded.push_str(&format!("{:02X}", byte));
}
}
}
encoded
}
pub struct BedrockProviderConfig {
pub region: String,
pub model_id: String,
pub profile: Option<String>,
pub access_key_id: Option<String>,
pub secret_access_key: Option<String>,
pub session_token: Option<String>,
pub timeout: Duration,
pub endpoint_url: Option<String>,
pub additional_model_request_fields: Option<serde_json::Value>,
base_url: String,
}
impl BedrockProviderConfig {
pub fn new(region: impl Into<String>, model_id: impl Into<String>) -> Self {
let region = region.into();
let model_id = model_id.into();
let base_url = format!(
"https://bedrock-runtime.{}.amazonaws.com/model/{}/converse",
region,
encode_path_segment(&model_id)
);
Self {
region,
model_id,
profile: None,
access_key_id: None,
secret_access_key: None,
session_token: None,
timeout: Duration::from_secs(DEFAULT_TIMEOUT_SECS),
endpoint_url: None,
additional_model_request_fields: None,
base_url,
}
}
pub fn with_profile(mut self, profile: impl Into<String>) -> Self {
self.profile = Some(profile.into());
self
}
pub fn with_credentials(
mut self,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
session_token: Option<String>,
) -> Self {
self.access_key_id = Some(access_key_id.into());
self.secret_access_key = Some(secret_access_key.into());
self.session_token = session_token;
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_endpoint_url(mut self, url: impl Into<String>) -> Self {
self.endpoint_url = Some(url.into());
self
}
pub fn with_additional_model_request_fields(mut self, fields: serde_json::Value) -> Self {
self.additional_model_request_fields = Some(fields);
self
}
}
impl ProviderConfig for BedrockProviderConfig {
fn base_url(&self) -> &str {
&self.base_url
}
fn model(&self) -> &str {
&self.model_id
}
fn api_key(&self) -> Option<&str> {
None
}
fn timeout(&self) -> Duration {
self.timeout
}
}