mixtape_core/model/
runtime.rs1use super::{BedrockModel, Model};
4use crate::provider::ProviderError;
5
6#[derive(Debug, Clone)]
12pub struct RuntimeBedrockModel {
13 name: String,
14 model_id: String,
15 context_tokens: usize,
16 output_tokens: usize,
17}
18
19impl RuntimeBedrockModel {
20 pub fn new(
22 name: impl Into<String>,
23 model_id: impl Into<String>,
24 context_tokens: usize,
25 output_tokens: usize,
26 ) -> Result<Self, ProviderError> {
27 let name = name.into();
28 let model_id = model_id.into();
29 if name.trim().is_empty() {
30 return Err(ProviderError::Configuration("Model name is empty".into()));
31 }
32 if model_id.is_empty()
35 || model_id.contains("://")
36 || (model_id.starts_with("arn:") && !model_id.contains(":bedrock:"))
37 || !model_id
38 .bytes()
39 .all(|c| c.is_ascii_alphanumeric() || b"._:/-".contains(&c))
40 {
41 return Err(ProviderError::Configuration(
42 "Expected a Bedrock model ID, inference-profile ID, or ARN".into(),
43 ));
44 }
45 if context_tokens == 0 || output_tokens == 0 || output_tokens > i32::MAX as usize {
46 return Err(ProviderError::Configuration(
47 "Token ceilings must be positive; output must fit Bedrock's i32 maxTokens".into(),
48 ));
49 }
50 Ok(Self {
51 name,
52 model_id,
53 context_tokens,
54 output_tokens,
55 })
56 }
57}
58
59impl Model for RuntimeBedrockModel {
60 fn name(&self) -> &str {
61 &self.name
62 }
63
64 fn max_context_tokens(&self) -> usize {
65 self.context_tokens
66 }
67
68 fn max_output_tokens(&self) -> usize {
69 self.output_tokens
70 }
71
72 fn estimate_token_count(&self, text: &str) -> usize {
73 text.len().div_ceil(4)
74 }
75}
76
77impl BedrockModel for RuntimeBedrockModel {
78 fn bedrock_id(&self) -> &str {
79 &self.model_id
80 }
81}