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}