Skip to main content

aimux_core/
files_model.rs

1//! The `Files` trait — the provider-facing interface for file management.
2//!
3//! Aligned with Vercel AI SDK `FilesV4`
4//! (`reference/ai/packages/provider/src/files/v4/`).
5//!
6//! Unlike the other model traits, the files interface uses `upload_file`
7//! (no `do_` prefix), matching the TS spec.
8
9use async_trait::async_trait;
10use serde::{Deserialize, Serialize};
11use ts_rs::TS;
12
13use crate::AbortSignal;
14use crate::error::AiMuxError;
15use crate::shared::{
16    FileBytes, SharedProviderMetadata, SharedProviderOptions, SharedProviderReference, Warning,
17};
18
19/// File data accepted by [`Files::upload_file`].
20///
21/// The V4 spec restricts upload input to the `data` and `text` variants of
22/// `SharedV4FileData` (URLs and provider references are not valid uploads), so
23/// this is a dedicated two-variant enum rather than the full [`crate::shared::FileData`].
24#[derive(Debug, Clone, Serialize, Deserialize, TS)]
25#[ts(export)]
26pub enum UploadFileData {
27    /// Raw bytes (`Uint8Array`) or a base64-encoded string.
28    Data { data: FileBytes },
29    /// Inline text content (UTF-8).
30    Text { text: String },
31}
32
33/// Options passed to [`Files::upload_file`].
34///
35/// Aligned with V4 `FilesV4UploadFileCallOptions`.
36#[derive(Debug, Clone, Serialize, Deserialize, TS)]
37#[ts(export)]
38pub struct UploadFileCallOptions {
39    /// The file data (raw bytes/base64 or inline text).
40    pub data: UploadFileData,
41
42    /// The IANA media type of the file, e.g. `"application/pdf"`.
43    pub media_type: String,
44
45    /// The filename of the file.
46    pub filename: Option<String>,
47
48    /// Additional provider-specific options, keyed by provider name.
49    pub provider_options: Option<SharedProviderOptions>,
50
51    /// Abort signal for cancelling the upload operation.
52    #[serde(skip)]
53    #[ts(skip)]
54    pub abort_signal: Option<AbortSignal>,
55}
56
57impl UploadFileCallOptions {
58    /// Create options with the given data and media type.
59    pub fn new(data: UploadFileData, media_type: impl Into<String>) -> Self {
60        Self {
61            data,
62            media_type: media_type.into(),
63            filename: None,
64            provider_options: None,
65            abort_signal: None,
66        }
67    }
68}
69
70/// Result of [`Files::upload_file`].
71///
72/// Aligned with V4 `FilesV4UploadFileResult`.
73#[derive(Debug, Clone, Serialize, Deserialize, TS)]
74#[ts(export)]
75pub struct UploadFileResult {
76    /// A provider reference mapping provider names to provider-specific file
77    /// identifiers.
78    pub provider_reference: SharedProviderReference,
79
80    /// The IANA media type of the uploaded file, if available from the
81    /// provider.
82    pub media_type: Option<String>,
83
84    /// The filename of the uploaded file, if available from the provider.
85    pub filename: Option<String>,
86
87    /// Additional provider-specific metadata, keyed by provider name.
88    pub provider_metadata: Option<SharedProviderMetadata>,
89
90    /// Warnings from the provider.
91    pub warnings: Vec<Warning>,
92}
93
94/// The unified file-management interface (provider-facing).
95///
96/// Aligned with V4 `FilesV4`. Named `Files` (dropping the `V4` suffix) to
97/// match the established convention of [`crate::language_model::LanguageModel`]
98/// et al.
99#[async_trait]
100pub trait Files: Send + Sync {
101    /// Specification version (always `"v4"`).
102    fn specification_version(&self) -> &'static str {
103        "v4"
104    }
105
106    /// Provider ID.
107    fn provider(&self) -> &str;
108
109    /// Upload a file to the provider and return a provider reference that can
110    /// be used in subsequent API calls.
111    ///
112    /// Note: this method has **no** `do_` prefix, matching the TS `FilesV4`
113    /// spec.
114    async fn upload_file(
115        &self,
116        options: &UploadFileCallOptions,
117    ) -> Result<UploadFileResult, AiMuxError>;
118}