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