pub use crate::transform::Converted;
use crate::transform::TransformError;
use crate::wire::claude::models as claude_models;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OpenAiModelSupplement {
pub owned_by: String,
pub created: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeModelSupplement {
pub display_name: Option<String>,
#[serde(default)]
pub line: Option<String>,
pub allowed_fallback_models: Vec<String>,
pub capabilities: ClaudeCapabilities,
pub max_input_tokens: Option<i64>,
pub max_tokens: Option<i64>,
pub created_at: Option<String>,
#[serde(default)]
pub lifecycle: Option<claude_models::ModelLifecycle>,
#[serde(default)]
pub deprecated_at: Option<String>,
#[serde(default)]
pub retires_at: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeCapabilities {
pub batch: bool,
pub citations: bool,
pub code_execution: bool,
pub context_management: ClaudeContextManagement,
pub effort: ClaudeEffort,
pub image_input: bool,
pub pdf_input: bool,
pub structured_outputs: bool,
#[serde(default)]
pub server_tools: Option<ClaudeServerTools>,
#[serde(default)]
pub compaction: Option<ClaudeCompaction>,
pub thinking: ClaudeThinking,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeContextManagement {
pub clear_thinking_20251015: bool,
pub clear_tool_uses_20250919: bool,
pub compact_20260112: bool,
pub supported: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeEffort {
pub high: bool,
pub low: bool,
pub max: bool,
pub medium: bool,
pub supported: bool,
pub xhigh: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeThinking {
pub supported: bool,
pub adaptive: bool,
pub enabled: bool,
#[serde(default)]
pub disabled: Option<bool>,
#[serde(default)]
pub between_tools: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeServerTools {
pub supported: bool,
pub web_search: bool,
pub code_execution: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClaudeCompaction {
pub supported: bool,
pub summarize: bool,
}
impl ClaudeCapabilities {
pub(crate) fn into_wire(self) -> claude_models::ModelCapabilities {
let support = |supported| claude_models::CapabilitySupport {
supported,
rest: Default::default(),
};
claude_models::ModelCapabilities {
batch: support(self.batch),
citations: support(self.citations),
code_execution: support(self.code_execution),
compaction: self.compaction.map(|value| {
Some(claude_models::CompactionCapability {
supported: value.supported,
summarize: support(value.summarize),
rest: Default::default(),
})
}),
context_management: claude_models::ContextManagementCapability {
clear_thinking_20251015: Some(support(
self.context_management.clear_thinking_20251015,
)),
clear_tool_uses_20250919: Some(support(
self.context_management.clear_tool_uses_20250919,
)),
compact_20260112: Some(support(self.context_management.compact_20260112)),
supported: self.context_management.supported,
rest: Default::default(),
},
effort: claude_models::EffortCapability {
high: support(self.effort.high),
low: support(self.effort.low),
max: support(self.effort.max),
medium: support(self.effort.medium),
supported: self.effort.supported,
xhigh: Some(support(self.effort.xhigh)),
rest: Default::default(),
},
image_input: support(self.image_input),
pdf_input: support(self.pdf_input),
structured_outputs: support(self.structured_outputs),
server_tools: self
.server_tools
.map(|tools| claude_models::ServerToolsCapability {
supported: tools.supported,
web_search: support(tools.web_search),
code_execution: support(tools.code_execution),
rest: Default::default(),
}),
thinking: claude_models::ThinkingCapability {
supported: self.thinking.supported,
types: claude_models::ThinkingTypes {
adaptive: support(self.thinking.adaptive),
enabled: support(self.thinking.enabled),
disabled: self.thinking.disabled.map(support),
between_tools: self.thinking.between_tools.map(support),
rest: Default::default(),
},
rest: Default::default(),
},
rest: Default::default(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GeminiModelSupplement {
pub base_model_id: String,
pub version: String,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListPageFacts {
pub complete: bool,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: Option<bool>,
pub next_page_token: Option<String>,
}
impl ListPageFacts {
pub const fn complete() -> Self {
Self {
complete: true,
first_id: None,
last_id: None,
has_more: Some(false),
next_page_token: None,
}
}
pub fn explicit(
first_id: impl Into<String>,
last_id: impl Into<String>,
has_more: bool,
) -> Self {
Self {
complete: false,
first_id: Some(first_id.into()),
last_id: Some(last_id.into()),
has_more: Some(has_more),
next_page_token: None,
}
}
pub fn with_next_page_token(mut self, token: impl Into<String>) -> Self {
self.next_page_token = Some(token.into());
self
}
}
pub(crate) fn missing_pagination(detail: &str) -> TransformError {
TransformError::new(
crate::transform::TransformErrorKind::MissingMetadata,
"pagination",
detail,
)
}