cookie_agent_models/adapters/
capabilities.rs1use crate::{
2 adapters::OvenAdapterFamily,
3 authoring::{CancellationCapability, MediaKind, Modality, ModelCapabilities, ReplayCapability},
4};
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
7pub enum AdapterCapabilityError {
8 #[error("unsupported_model_capabilities")]
9 Unsupported,
10}
11
12pub fn validate_capability_ceiling(
13 family: OvenAdapterFamily,
14 capabilities: &ModelCapabilities,
15) -> Result<(), AdapterCapabilityError> {
16 if capabilities
17 .output
18 .iter()
19 .any(|value| *value != Modality::Text)
20 || capabilities.cancellation != CancellationCapability::LocalOnly
21 || capabilities.parallel_tool_calls && !capabilities.tool_calling
22 || capabilities.context_tokens == 0
23 || capabilities.output_tokens == 0
24 || capabilities.output_tokens > capabilities.context_tokens
25 {
26 return Err(AdapterCapabilityError::Unsupported);
27 }
28 if capabilities.reasoning
29 && matches!(
30 family,
31 OvenAdapterFamily::OpenaiResponses | OvenAdapterFamily::AzureOpenaiResponses
32 )
33 && capabilities.native_replay == ReplayCapability::Unsupported
34 {
35 return Err(AdapterCapabilityError::Unsupported);
36 }
37 let compaction_supported = matches!(
38 family,
39 OvenAdapterFamily::OpenaiResponses | OvenAdapterFamily::AzureOpenaiResponses
40 );
41 if capabilities.compaction == crate::CompactionCapability::Native && !compaction_supported {
42 return Err(AdapterCapabilityError::Unsupported);
43 }
44 for (kind, media) in &capabilities.media {
45 let modality = match kind {
46 MediaKind::Image => Modality::Image,
47 MediaKind::Audio => Modality::Audio,
48 MediaKind::Pdf => Modality::Pdf,
49 MediaKind::Video => Modality::Video,
50 };
51 if !capabilities.input.contains(&modality)
52 || media.mime_types.is_empty()
53 || media.max_bytes == 0
54 || media.max_count == 0
55 {
56 return Err(AdapterCapabilityError::Unsupported);
57 }
58 }
59 if capabilities
60 .input
61 .iter()
62 .filter(|modality| **modality != Modality::Text)
63 .any(|modality| {
64 let kind = match modality {
65 Modality::Image => MediaKind::Image,
66 Modality::Audio => MediaKind::Audio,
67 Modality::Pdf => MediaKind::Pdf,
68 Modality::Video => MediaKind::Video,
69 Modality::Text => unreachable!(),
70 };
71 !capabilities.media.contains_key(&kind)
72 })
73 {
74 return Err(AdapterCapabilityError::Unsupported);
75 }
76 Ok(())
77}